• 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::__anonaf246e430111::ExternalTestConfig384 	ExternalTestConfig	(VkFormat				format_,
385 						 UVec2					imageSize_,
386 						 vector<RenderPass>		renderPasses_,
387 						 RenderingType			renderingType_,
388 						 SynchronizationType	synchronizationType_,
389 						 deUint32				blurKernel_ = 4)
390 		: format				(format_)
391 		, imageSize				(imageSize_)
392 		, renderPasses			(renderPasses_)
393 		, renderingType			(renderingType_)
394 		, synchronizationType	(synchronizationType_)
395 		, blurKernel			(blurKernel_)
396 	{
397 	}
398 
399 	VkFormat			format;
400 	UVec2				imageSize;
401 	vector<RenderPass>	renderPasses;
402 	RenderingType		renderingType;
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 RenderingType					renderingType,
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 RenderingType						m_renderingType;
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.renderingType == RENDERING_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
500 	, m_synchronization2Supported	((testConfig.synchronizationType == SYNCHRONIZATION_TYPE_SYNCHRONIZATION2) && context.requireDeviceFunctionality("VK_KHR_synchronization2"))
501 	, m_renderingType				(testConfig.renderingType)
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.renderingType, 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 RenderingType renderingType,const SynchronizationType synchronizationType)612 vector<SharedPtrVkRenderPass> ExternalDependencyTestInstance::createRenderPasses (const DeviceInterface&	vkd,
613 																				  VkDevice					device,
614 																				  vector<RenderPass>		renderPassInfos,
615 																				  const RenderingType		renderingType,
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, renderingType, 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_renderingType)
790 	{
791 		case RENDERING_TYPE_RENDERPASS_LEGACY:
792 			return iterateInternal<RenderpassSubpass1>();
793 		case RENDERING_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::__anonaf246e430111::SubpassTestConfig990 		SubpassTestConfig	(VkFormat		format_,
991 							 UVec2			imageSize_,
992 							 RenderPass		renderPass_,
993 							 RenderingType	renderingType_)
994 		: format			(format_)
995 		, imageSize			(imageSize_)
996 		, renderPass		(renderPass_)
997 		, renderingType		(renderingType_)
998 	{
999 	}
1000 
1001 	VkFormat			format;
1002 	UVec2				imageSize;
1003 	RenderPass			renderPass;
1004 	RenderingType		renderingType;
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 RenderingType					m_renderingType;
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.renderingType == RENDERING_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
1099 	, m_renderPassInfo				(testConfig.renderPass)
1100 	, m_renderingType				(testConfig.renderingType)
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.renderingType))
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_renderingType)
1442 	{
1443 		case RENDERING_TYPE_RENDERPASS_LEGACY:
1444 			return iterateInternal<RenderpassSubpass1>();
1445 		case RENDERING_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::__anonaf246e430111::SubpassSelfDependencyBackwardsTestConfig1810 		SubpassSelfDependencyBackwardsTestConfig	(VkFormat		format_,
1811 													 UVec2			imageSize_,
1812 													 RenderingType	renderingType_)
1813 		: format			(format_)
1814 		, imageSize			(imageSize_)
1815 		, renderingType		(renderingType_)
1816 	{
1817 	}
1818 
1819 	VkFormat		format;
1820 	UVec2			imageSize;
1821 	RenderingType	renderingType;
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 RenderingType		m_renderingType;
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.renderingType == RENDERING_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
1851 	, m_featuresSupported	(context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER))
1852 	, m_renderingType		(testConfig.renderingType)
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_renderingType)
1866 	{
1867 		case RENDERING_TYPE_RENDERPASS_LEGACY:
1868 			return iterateInternal<RenderpassSubpass1>();
1869 		case RENDERING_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_renderingType);
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::__anonaf246e430111::SeparateChannelsTestConfig2273 		SeparateChannelsTestConfig	(VkFormat		format_,
2274 									 RenderingType	renderingType_)
2275 		: format			(format_)
2276 		, renderingType		(renderingType_)
2277 	{
2278 	}
2279 
2280 	VkFormat		format;
2281 	RenderingType	renderingType;
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 RenderingType		m_renderingType;
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.renderingType == RENDERING_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
2310 	, m_renderingType		(testConfig.renderingType)
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_renderingType)
2324 	{
2325 		case RENDERING_TYPE_RENDERPASS_LEGACY:
2326 			return iterateInternal<RenderpassSubpass1>();
2327 		case RENDERING_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>									imageView;
2360 	Move<VkImageView>									dsImageView;
2361 	Move<VkPipelineLayout>								pipelineLayout;
2362 	Move<VkPipeline>									renderPipeline;
2363 	Move<VkFramebuffer>									framebuffer;
2364 	Move<VkRenderPass>									renderPass;
2365 	Move<VkBuffer>										resultBuffer0;
2366 	de::MovePtr<Allocation>								resultBuffer0Memory;
2367 	Move<VkBuffer>										resultBuffer1;
2368 	de::MovePtr<Allocation>								resultBuffer1Memory;
2369 	Move<VkBuffer>										vertexBuffer;
2370 	de::MovePtr<Allocation>								vertexBufferMemory;
2371 
2372 	const VkExtent3D		imageExtent		=
2373 	{
2374 		m_width,	// deUint32	width
2375 		m_height,	// deUint32	height
2376 		1u			// deUint32	depth
2377 	};
2378 
2379 	// Create image used for both input and output in case of color test, and as a color output in depth/stencil test.
2380 	{
2381 		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;
2382 
2383 		const VkImageCreateInfo	imageCreateInfo	=
2384 		{
2385 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
2386 			DE_NULL,								// const void*				pNext
2387 			0u,										// VkImageCreateFlags		flags
2388 			VK_IMAGE_TYPE_2D,						// VkImageType				imageType
2389 			colorFormat,							// VkFormat					format
2390 			imageExtent,							// VkExtent3D				extent
2391 			1u,										// uint32_t					mipLevels
2392 			1u,										// uint32_t					arrayLayers
2393 			VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
2394 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
2395 			usage,									// VkImageUsageFlags		usage
2396 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
2397 			1u,										// uint32_t					queueFamilyIndexCount
2398 			&queueFamilyIndex,						// const uint32_t*			pQueueFamilyIndices
2399 			VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
2400 		};
2401 
2402 		checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);
2403 
2404 		colorImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
2405 		colorImageAllocation = m_context.getDefaultAllocator().allocate(getImageMemoryRequirements(vkd, device, *colorImage), MemoryRequirement::Any);
2406 		VK_CHECK(vkd.bindImageMemory(device, *colorImage, colorImageAllocation->getMemory(), colorImageAllocation->getOffset()));
2407 	}
2408 
2409 	// Create depth/stencil image
2410 	if (isDSFormat)
2411 	{
2412 		VkImageUsageFlags		usage			= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2413 
2414 		const VkImageCreateInfo	imageCreateInfo	=
2415 		{
2416 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
2417 			DE_NULL,								// const void*				pNext
2418 			0u,										// VkImageCreateFlags		flags
2419 			VK_IMAGE_TYPE_2D,						// VkImageType				imageType
2420 			m_format,								// VkFormat					format
2421 			imageExtent,							// VkExtent3D				extent
2422 			1u,										// uint32_t					mipLevels
2423 			1u,										// uint32_t					arrayLayers
2424 			VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
2425 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
2426 			usage,									// VkImageUsageFlags		usage
2427 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
2428 			1u,										// uint32_t					queueFamilyIndexCount
2429 			&queueFamilyIndex,						// const uint32_t*			pQueueFamilyIndices
2430 			VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
2431 		};
2432 
2433 		checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);
2434 
2435 		dsImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
2436 		dsImageAllocation = m_context.getDefaultAllocator().allocate(getImageMemoryRequirements(vkd, device, *dsImage), MemoryRequirement::Any);
2437 		VK_CHECK(vkd.bindImageMemory(device, *dsImage, dsImageAllocation->getMemory(), dsImageAllocation->getOffset()));
2438 
2439 		// Initialize depth / stencil image
2440 		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);
2441 	}
2442 
2443 	// Initialize color image
2444 	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);
2445 
2446 	// Create color image views
2447 	{
2448 		const VkImageViewCreateInfo imageViewCreateInfo =
2449 		{
2450 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType
2451 			DE_NULL,									// const void*				pNext
2452 			0u,											// VkImageViewCreateFlags	flags
2453 			*colorImage,								// VkImage					image
2454 			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType
2455 			colorFormat,								// VkFormat					format
2456 			makeComponentMappingRGBA(),					// VkComponentMapping		components
2457 			{											// VkImageSubresourceRange	subresourceRange
2458 				VK_IMAGE_ASPECT_COLOR_BIT,
2459 				0u,
2460 				1u,
2461 				0u,
2462 				1u
2463 			}
2464 		};
2465 
2466 		imageView = createImageView(vkd, device, &imageViewCreateInfo);
2467 	}
2468 
2469 	// Create depth/stencil image view
2470 	if (isDSFormat)
2471 	{
2472 		const VkImageViewCreateInfo imageViewCreateInfo =
2473 		{
2474 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType
2475 			DE_NULL,									// const void*				pNext
2476 			0u,											// VkImageViewCreateFlags	flags
2477 			*dsImage,									// VkImage					image
2478 			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType
2479 			m_format,									// VkFormat					format
2480 			makeComponentMappingRGBA(),					// VkComponentMapping		components
2481 			{											// VkImageSubresourceRange	subresourceRange
2482 				VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
2483 				0u,
2484 				1u,
2485 				0u,
2486 				1u
2487 			}
2488 		};
2489 
2490 		dsImageView	= createImageView(vkd, device, &imageViewCreateInfo);
2491 	}
2492 
2493 	// Create result buffers.
2494 	{
2495 		resultBuffer0		= createBuffer(vkd, device, m_format, m_width, m_height);
2496 		resultBuffer0Memory	= createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *resultBuffer0);
2497 		resultBuffer1		= createBuffer(vkd, device, m_format, m_width, m_height);
2498 		resultBuffer1Memory	= createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *resultBuffer1);
2499 	}
2500 
2501 	// Create descriptor set layout.
2502 	Unique<VkDescriptorSetLayout>	descriptorSetLayout	(DescriptorSetLayoutBuilder()
2503 			.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
2504 			.build(vkd, device));
2505 	// Create descriptor pool.
2506 	Unique<VkDescriptorPool>		descriptorPool		(DescriptorPoolBuilder()
2507 			.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u)
2508 			.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
2509 	// Create descriptor set.
2510 	Unique<VkDescriptorSet>			descriptorSet		(makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout));
2511 
2512 	// Update descriptor set information.
2513 	if (!isDSFormat)
2514 	{
2515 		VkDescriptorImageInfo descInputAttachment = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
2516 
2517 		DescriptorSetUpdateBuilder()
2518 			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descInputAttachment)
2519 			.update(vkd, device);
2520 	}
2521 
2522 	// Create render pipeline layout.
2523 	{
2524 		const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
2525 		{
2526 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType
2527 			DE_NULL,										// const void*					pNext
2528 			(vk::VkPipelineLayoutCreateFlags)0,				// VkPipelineLayoutCreateFlags	flags
2529 			1u,												// deUint32						setLayoutCount
2530 			&*descriptorSetLayout,							// const VkDescriptorSetLayout*	pSetLayouts
2531 			0u,												// deUint32						pushConstantRangeCount
2532 			DE_NULL											// const VkPushConstantRange*	pPushConstantRanges
2533 		};
2534 
2535 		pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
2536 	}
2537 
2538 	// Create render pass.
2539 	{
2540 		vector<Attachment>			attachments;
2541 		vector<AttachmentReference>	colorAttachmentReferences;
2542 		vector<AttachmentReference>	inputAttachmentReferences;
2543 		AttachmentReference			dsAttachmentReference		(1u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
2544 
2545 		const VkImageAspectFlags	inputAttachmentAspectMask	((m_renderingType == RENDERING_TYPE_RENDERPASS2)
2546 																? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT)
2547 																: static_cast<VkImageAspectFlags>(0));
2548 
2549 		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));
2550 		colorAttachmentReferences.push_back(AttachmentReference(0u, colorImageLayout));
2551 
2552 		if (isDSFormat)
2553 		{
2554 			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));
2555 		}
2556 		else
2557 		{
2558 			inputAttachmentReferences.push_back(AttachmentReference(0u, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask));
2559 		}
2560 
2561 		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>()));
2562 		vector<SubpassDependency> subpassDependency;
2563 		if(!isDSFormat)
2564 		{
2565 			/* Self supass-dependency */
2566 			subpassDependency.push_back(SubpassDependency(0u, 0u, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2567 							VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, VK_DEPENDENCY_BY_REGION_BIT));
2568 		}
2569 		renderPass = createRenderPass(vkd, device, RenderPass(attachments, subpasses, subpassDependency), m_renderingType);
2570 
2571 	}
2572 
2573 	// Create render pipeline.
2574 	{
2575 		const Unique<VkShaderModule>				vertexShaderModule			(createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u));
2576 		const Unique<VkShaderModule>				fragmentShaderModule		(createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u));
2577 
2578 		const VkVertexInputBindingDescription		vertexBinding0				=
2579 		{
2580 			0u,							// deUint32					binding
2581 			sizeof(Vec4),				// deUint32					strideInBytes
2582 			VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputStepRate	stepRate
2583 		};
2584 
2585 		const VkVertexInputAttributeDescription		attr0						=
2586 		{
2587 			0u,								// deUint32	location
2588 			0u,								// deUint32	binding
2589 			VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format
2590 			0u								// deUint32	offsetInBytes
2591 		};
2592 
2593 		const VkPipelineVertexInputStateCreateInfo	vertexInputState			=
2594 		{
2595 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType
2596 			DE_NULL,													// const void*								pNext
2597 			(VkPipelineVertexInputStateCreateFlags)0u,					// VkPipelineVertexInputStateCreateFlags	flags
2598 			1u,															// deUint32									vertexBindingDescriptionCount
2599 			&vertexBinding0,											// const VkVertexInputBindingDescription*	pVertexBindingDescriptions
2600 			1u,															// deUint32									vertexAttributeDescriptionCount
2601 			&attr0														// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions
2602 		};
2603 
2604 		// Use write mask to enable only B and A channels to prevent self dependency (reads are done for channels R and G).
2605 		const VkPipelineColorBlendAttachmentState	colorBlendAttachmentState	=
2606 		{
2607 			VK_FALSE,					// VkBool32					blendEnable
2608 			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			srcColorBlendFactor
2609 			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			dstColorBlendFactor
2610 			VK_BLEND_OP_ADD,			// VkBlendOp				colorBlendOp
2611 			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			srcAlphaBlendFactor
2612 			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			dstAlphaBlendFactor
2613 			VK_BLEND_OP_ADD,			// VkBlendOp				alphaBlendOp
2614 			VK_COLOR_COMPONENT_B_BIT
2615 			| VK_COLOR_COMPONENT_A_BIT	// VkColorComponentFlags	colorWriteMask
2616 		};
2617 
2618 		const VkPipelineColorBlendStateCreateInfo	colorBlendState				=
2619 		{
2620 			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType
2621 			DE_NULL,													// const void*									pNext
2622 			0u,															// VkPipelineColorBlendStateCreateFlags			flags
2623 			VK_FALSE,													// VkBool32										logicOpEnable
2624 			VK_LOGIC_OP_CLEAR,											// VkLogicOp									logicOp
2625 			1u,															// deUint32										attachmentCount
2626 			&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments
2627 			{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4]
2628 		};
2629 
2630 		const VkStencilOpState						stencilOpState				=
2631 		{
2632 			VK_STENCIL_OP_REPLACE,	// VkStencilOp	failOp
2633 			VK_STENCIL_OP_REPLACE,	// VkStencilOp	passOp
2634 			VK_STENCIL_OP_ZERO,		// VkStencilOp	depthFailOp
2635 			VK_COMPARE_OP_ALWAYS,	// VkCompareOp	compareOp
2636 			0xff,					// deUint32		compareMask
2637 			0xff,					// deUint32		writeMask
2638 			stencilRefValue			// deUint32		reference
2639 		};
2640 
2641 		const VkPipelineDepthStencilStateCreateInfo	depthStencilState			=
2642 		{
2643 			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType
2644 			DE_NULL,													// const void*								pNext
2645 			0u,															// VkPipelineDepthStencilStateCreateFlags	flags
2646 			VK_TRUE,													// VkBool32									depthTestEnable
2647 			VK_FALSE,													// VkBool32									depthWriteEnable
2648 			VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp
2649 			VK_FALSE,													// VkBool32									depthBoundsTestEnable
2650 			VK_TRUE,													// VkBool32									stencilTestEnable
2651 			stencilOpState,												// VkStencilOpState							front
2652 			stencilOpState,												// VkStencilOpState							back
2653 			0.0f,														// float									minDepthBounds
2654 			1.0f														// float									maxDepthBounds
2655 		};
2656 
2657 		const std::vector<VkViewport>				viewports					(1, makeViewport(tcu::UVec2(m_width, m_height)));
2658 		const std::vector<VkRect2D>					scissors					(1, makeRect2D(tcu::UVec2(m_width, m_height)));
2659 
2660 		renderPipeline = makeGraphicsPipeline(vkd,			// const DeviceInterface&							vk
2661 				device,										// const VkDevice									device
2662 				*pipelineLayout,							// const VkPipelineLayout							pipelineLayout
2663 				*vertexShaderModule,						// const VkShaderModule								vertexShaderModule
2664 				DE_NULL,									// const VkShaderModule								tessellationControlShaderModule
2665 				DE_NULL,									// const VkShaderModule								tessellationEvalShaderModule
2666 				DE_NULL,									// const VkShaderModule								geometryShaderModule
2667 				*fragmentShaderModule,						// const VkShaderModule								fragmentShaderModule
2668 				*renderPass,								// const VkRenderPass								renderPass
2669 				viewports,									// const std::vector<VkViewport>&					viewports
2670 				scissors,									// const std::vector<VkRect2D>&						scissors
2671 				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,		// const VkPrimitiveTopology						topology
2672 				0u,											// const deUint32									subpass
2673 				0u,											// const deUint32									patchControlPoints
2674 				&vertexInputState,							// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
2675 				DE_NULL,									// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
2676 				DE_NULL,									// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
2677 				isDSFormat ? &depthStencilState : DE_NULL,	// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
2678 				isDSFormat ? DE_NULL : &colorBlendState);	// const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo
2679 	}
2680 
2681 	// Create framebuffer.
2682 	{
2683 		const VkImageView				dsAttachments[]			=
2684 		{
2685 			*imageView,
2686 			*dsImageView
2687 		};
2688 
2689 		const VkFramebufferCreateInfo	framebufferCreateInfo	=
2690 		{
2691 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType
2692 			DE_NULL,									// const void*				pNext
2693 			0u,											// VkFramebufferCreateFlags	flags
2694 			*renderPass,								// VkRenderPass				renderPass
2695 			isDSFormat ? 2u : 1u,						// uint32_t					attachmentCount
2696 			isDSFormat ? dsAttachments : &*imageView,	// const VkImageView*		pAttachments
2697 			m_width,									// uint32_t					width
2698 			m_height,									// uint32_t					height
2699 			1u											// uint32_t					layers
2700 		};
2701 
2702 		framebuffer = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
2703 	}
2704 
2705 	// Generate quad vertices
2706 	{
2707 		const tcu::Vec4	lowerLeftVertex		(-1.0f, -1.0f, 0.5f, 1.0f);
2708 		const tcu::Vec4	lowerRightVertex	(1.0f, -1.0f, 0.5f, 1.0f);
2709 		const tcu::Vec4	upperLeftVertex		(-1.0f, 1.0f, 0.5f, 1.0f);
2710 		const tcu::Vec4	upperRightVertex	(1.0f, 1.0f, 0.5f, 1.0f);
2711 
2712 		vertexData.push_back(lowerLeftVertex);
2713 		vertexData.push_back(upperLeftVertex);
2714 		vertexData.push_back(lowerRightVertex);
2715 		vertexData.push_back(upperRightVertex);
2716 	}
2717 
2718 	// Upload vertex data.
2719 	{
2720 		const size_t				vertexDataSize		= vertexData.size() * sizeof(Vec4);
2721 
2722 		const VkBufferCreateInfo	vertexBufferParams	=
2723 		{
2724 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	//	VkStructureType		sType
2725 			DE_NULL,								//	const void*			pNext
2726 			0u,										//	VkBufferCreateFlags	flags
2727 			(VkDeviceSize)vertexDataSize,			//	VkDeviceSize		size
2728 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		//	VkBufferUsageFlags	usage
2729 			VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode		sharingMode
2730 			1u,										//	deUint32			queueFamilyCount
2731 			&queueFamilyIndex,						//	const deUint32*		pQueueFamilyIndices
2732 		};
2733 
2734 		vertexBuffer		= createBuffer(vkd, m_context.getDevice(), &vertexBufferParams);
2735 		vertexBufferMemory	= createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *vertexBuffer);
2736 
2737 		deMemcpy(vertexBufferMemory->getHostPtr(), vertexData.data(), vertexDataSize);
2738 		flushAlloc(vkd, device, *vertexBufferMemory);
2739 	}
2740 
2741 	beginCommandBuffer(vkd, *commandBuffer);
2742 	vkd.cmdBindPipeline(*commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *renderPipeline);
2743 
2744 	if (!isDSFormat)
2745 		vkd.cmdBindDescriptorSets(*commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
2746 
2747 	// Begin render pass.
2748 	{
2749 		VkRect2D					renderArea	=
2750 		{
2751 			{ 0u, 0u },				// VkOffset2D	offset
2752 			{ m_width, m_height }	// VkExtent2D	extent
2753 		};
2754 
2755 		const VkRenderPassBeginInfo	beginInfo	=
2756 		{
2757 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType
2758 			DE_NULL,									// const void*			pNext
2759 			*renderPass,								// VkRenderPass			renderPass
2760 			*framebuffer,								// VkFramebuffer		framebuffer
2761 			renderArea,									// VkRect2D				renderArea
2762 			0u,											// uint32_t				clearValueCount
2763 			DE_NULL										// const VkClearValue*	pClearValues
2764 		};
2765 
2766 		RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
2767 	}
2768 
2769 	const VkDeviceSize bindingOffset = 0;
2770 
2771 	vkd.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
2772 	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *renderPipeline);
2773 
2774 	if(!isDSFormat)
2775 	{
2776 		const VkImageMemoryBarrier	imageBarrier	=
2777 		{
2778 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
2779 			DE_NULL,										// const void*				pNext;
2780 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			srcAccessMask;
2781 			VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,			// VkAccessFlags			dstAccessMask;
2782 			VK_IMAGE_LAYOUT_GENERAL,						// VkImageLayout			oldLayout;
2783 			VK_IMAGE_LAYOUT_GENERAL,						// VkImageLayout			newLayout;
2784 			VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
2785 			VK_QUEUE_FAMILY_IGNORED,						// deUint32					destQueueFamilyIndex;
2786 			*colorImage,									// VkImage					image;
2787 			makeImageSubresourceRange(1u, 0u, 1u, 0, 1u)	// VkImageSubresourceRange	subresourceRange;
2788 		};
2789 		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2790 						VK_DEPENDENCY_BY_REGION_BIT, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
2791 	}
2792 
2793 	vkd.cmdDraw(*commandBuffer, 4u, 1u, 0u, 0u);
2794 	RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
2795 
2796 	// Copy results to a buffer.
2797 	if (isDSFormat)
2798 	{
2799 		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);
2800 	}
2801 	else
2802 	{
2803 		copyImageToBuffer(vkd, *commandBuffer, *colorImage, *resultBuffer0, tcu::IVec2(m_width, m_height), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
2804 	}
2805 
2806 	endCommandBuffer(vkd, *commandBuffer);
2807 	submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
2808 	invalidateMappedMemoryRange(vkd, m_context.getDevice(), resultBuffer0Memory->getMemory(), resultBuffer0Memory->getOffset(), VK_WHOLE_SIZE);
2809 	invalidateMappedMemoryRange(vkd, m_context.getDevice(), resultBuffer1Memory->getMemory(), resultBuffer1Memory->getOffset(), VK_WHOLE_SIZE);
2810 
2811 	// Verify result.
2812 	{
2813 		const tcu::TextureFormat	format		(mapVkFormat(m_format));
2814 		tcu::TextureLevel			reference	(format, m_width, m_height);
2815 
2816 		if (isDSFormat)
2817 		{
2818 			const void* const					ptrDepth				(resultBuffer0Memory->getHostPtr());
2819 			const void* const					ptrStencil				(resultBuffer1Memory->getHostPtr());
2820 			const tcu::ConstPixelBufferAccess	resultDepthAccess		(getDepthCopyFormat(m_format), m_width, m_height, 1, ptrDepth);
2821 			const tcu::ConstPixelBufferAccess	resultStencilAccess		(getStencilCopyFormat(m_format), m_width, m_height, 1, ptrStencil);
2822 			const PixelBufferAccess				referenceDepthAccess	(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH));
2823 			const PixelBufferAccess				referenceStencilAccess	(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL));
2824 			const float							depthThreshold			(1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(resultDepthAccess.getFormat()).cast<deUint32>()) - 1u).cast<float>().x());
2825 
2826 			for (deUint32 x = 0; x < m_width; x++)
2827 				for (deUint32 y = 0; y < m_height; y++)
2828 				{
2829 					float depthValue = ((x / tileSize) % 2 != (y / tileSize) % 2) ? depthInitValues[0] : depthInitValues[1];
2830 					referenceDepthAccess.setPixDepth(depthValue, x, y, 0);
2831 					referenceStencilAccess.setPixel(tcu::IVec4(0.5f < depthValue ? stencilRefValue : 0), x, y, 0);
2832 				}
2833 
2834 			if (!verifyDepth(m_context, reference.getAccess(), resultDepthAccess, depthThreshold))
2835 				m_resultCollector.fail("Depth compare failed.");
2836 
2837 			if (!verifyStencil(m_context, referenceStencilAccess, resultStencilAccess))
2838 				m_resultCollector.fail("Stencil compare failed.");
2839 		}
2840 		else
2841 		{
2842 			const void* const					ptrResult		(resultBuffer0Memory->getHostPtr());
2843 			const tcu::ConstPixelBufferAccess	resultAccess	(format, m_width, m_height, 1, ptrResult);
2844 			const PixelBufferAccess				referenceAccess	(reference.getAccess());
2845 
2846 			for (deUint32 x = 0; x < m_width; x++)
2847 				for (deUint32 y = 0; y < m_height; y++)
2848 				{
2849 					const tcu::Vec4	initValue	= ((x / tileSize) % 2 != (y / tileSize) % 2) ? colorInitValues[0] : colorInitValues[1];
2850 					const tcu::Vec4	refValue	= tcu::Vec4(initValue.x(), initValue.y(), initValue.x() + initValue.y(), 1.0f);
2851 
2852 					referenceAccess.setPixel(refValue, x, y, 0);
2853 				}
2854 
2855 			if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(),	// log
2856 											"Rendered result",						// imageSetName
2857 											"",										// imageSetDesc
2858 											referenceAccess,						// reference
2859 											resultAccess,							// result
2860 											Vec4(0.01f),							// threshold
2861 											tcu::COMPARE_LOG_RESULT))				// logMode
2862 			{
2863 				m_resultCollector.fail("Image compare failed.");
2864 			}
2865 		}
2866 
2867 	}
2868 
2869 	return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
2870 }
2871 
2872 struct SingleAttachmentTestConfig
2873 {
SingleAttachmentTestConfigvkt::__anonaf246e430111::SingleAttachmentTestConfig2874 		SingleAttachmentTestConfig	(VkFormat		format_,
2875 									 RenderingType	renderingType_)
2876 		: format			(format_)
2877 		, renderingType		(renderingType_)
2878 	{
2879 	}
2880 
2881 	VkFormat		format;
2882 	RenderingType	renderingType;
2883 };
2884 
2885 class SingleAttachmentTestInstance : public TestInstance
2886 {
2887 public:
2888 							SingleAttachmentTestInstance	(Context&					context,
2889 															 SingleAttachmentTestConfig	testConfig);
2890 
2891 							~SingleAttachmentTestInstance	(void);
2892 
2893 	tcu::TestStatus			iterate							(void);
2894 
2895 	template<typename RenderpassSubpass>
2896 	tcu::TestStatus			iterateInternal					(void);
2897 
2898 private:
2899 	const bool				m_extensionSupported;
2900 	const RenderingType		m_renderingType;
2901 
2902 	const deUint32			m_width;
2903 	const deUint32			m_height;
2904 	const VkFormat			m_format;
2905 	tcu::ResultCollector	m_resultCollector;
2906 };
2907 
SingleAttachmentTestInstance(Context & context,SingleAttachmentTestConfig testConfig)2908 SingleAttachmentTestInstance::SingleAttachmentTestInstance (Context& context, SingleAttachmentTestConfig testConfig)
2909 	: TestInstance			(context)
2910 	, m_extensionSupported	((testConfig.renderingType == RENDERING_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
2911 	, m_renderingType		(testConfig.renderingType)
2912 	, m_width				(256u)
2913 	, m_height				(256u)
2914 	, m_format				(testConfig.format)
2915 {
2916 }
2917 
~SingleAttachmentTestInstance(void)2918 SingleAttachmentTestInstance::~SingleAttachmentTestInstance (void)
2919 {
2920 }
2921 
iterate(void)2922 tcu::TestStatus SingleAttachmentTestInstance::iterate (void)
2923 {
2924 	switch (m_renderingType)
2925 	{
2926 		case RENDERING_TYPE_RENDERPASS_LEGACY:
2927 			return iterateInternal<RenderpassSubpass1>();
2928 		case RENDERING_TYPE_RENDERPASS2:
2929 			return iterateInternal<RenderpassSubpass2>();
2930 		default:
2931 			TCU_THROW(InternalError, "Impossible");
2932 	}
2933 }
2934 
2935 template<typename RenderpassSubpass>
iterateInternal(void)2936 tcu::TestStatus SingleAttachmentTestInstance::iterateInternal (void)
2937 {
2938 	const DeviceInterface&								vkd					(m_context.getDeviceInterface());
2939 	const VkDevice										device				= m_context.getDevice();
2940 	const VkQueue										queue				= m_context.getUniversalQueue();
2941 	const deUint32										queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
2942 	const Unique<VkCommandPool>							commandPool			(createCommandPool(vkd, m_context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
2943 	const Unique<VkCommandBuffer>						commandBuffer		(allocateCommandBuffer(vkd, m_context.getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2944 	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo	(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
2945 	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo		(DE_NULL);
2946 	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) };
2947 	const VkExtent3D									imageExtent			= { m_width, m_height, 1u };
2948 	vector<Vec4>										vertexData;
2949 	Move<VkImage>										colorImage;
2950 	Move<VkImage>										resultImage;
2951 	de::MovePtr<Allocation>								colorImageAllocation;
2952 	de::MovePtr<Allocation>								resultImageAllocation;
2953 	Move<VkImageView>									imageViewInput;
2954 	Move<VkImageView>									imageViewResult;
2955 	Move<VkPipelineLayout>								pipelineLayoutInput;
2956 	Move<VkPipelineLayout>								pipelineLayoutImageSampler;
2957 	Move<VkPipeline>									pipelineSolidColor;
2958 	Move<VkPipeline>									pipelineInputAtt;
2959 	Move<VkPipeline>									pipelineImageSampler;
2960 	Move<VkFramebuffer>									framebuffer1;
2961 	Move<VkFramebuffer>									framebuffer0;
2962 	Move<VkRenderPass>									renderPass0;
2963 	Move<VkRenderPass>									renderPass1;
2964 	Move<VkBuffer>										resultBuffer;
2965 	de::MovePtr<Allocation>								resultBufferMemory;
2966 	Move<VkBuffer>										vertexBuffer;
2967 	de::MovePtr<Allocation>								vertexBufferMemory;
2968 	Move<VkSampler>										sampler;
2969 
2970 	// Create image used for both input and output.
2971 	{
2972 		VkImageUsageFlags		usage			= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
2973 												  | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT
2974 												  | VK_IMAGE_USAGE_SAMPLED_BIT;
2975 
2976 		const VkImageCreateInfo	imageCreateInfo	=
2977 		{
2978 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
2979 			DE_NULL,								// const void*				pNext
2980 			0u,										// VkImageCreateFlags		flags
2981 			VK_IMAGE_TYPE_2D,						// VkImageType				imageType
2982 			m_format,								// VkFormat					format
2983 			imageExtent,							// VkExtent3D				extent
2984 			1u,										// uint32_t					mipLevels
2985 			1u,										// uint32_t					arrayLayers
2986 			VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
2987 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
2988 			usage,									// VkImageUsageFlags		usage
2989 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
2990 			1u,										// uint32_t					queueFamilyIndexCount
2991 			&queueFamilyIndex,						// const uint32_t*			pQueueFamilyIndices
2992 			VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
2993 		};
2994 
2995 		checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);
2996 
2997 		colorImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
2998 		colorImageAllocation = m_context.getDefaultAllocator().allocate(getImageMemoryRequirements(vkd, device, *colorImage), MemoryRequirement::Any);
2999 		VK_CHECK(vkd.bindImageMemory(device, *colorImage, colorImageAllocation->getMemory(), colorImageAllocation->getOffset()));
3000 	}
3001 
3002 	// Create image used for final result.
3003 	{
3004 		VkImageUsageFlags		usage			= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3005 
3006 		const VkImageCreateInfo	imageCreateInfo	=
3007 		{
3008 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
3009 			DE_NULL,								// const void*				pNext
3010 			0u,										// VkImageCreateFlags		flags
3011 			VK_IMAGE_TYPE_2D,						// VkImageType				imageType
3012 			m_format,								// VkFormat					format
3013 			imageExtent,							// VkExtent3D				extent
3014 			1u,										// uint32_t					mipLevels
3015 			1u,										// uint32_t					arrayLayers
3016 			VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
3017 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
3018 			usage,									// VkImageUsageFlags		usage
3019 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
3020 			1u,										// uint32_t					queueFamilyIndexCount
3021 			&queueFamilyIndex,						// const uint32_t*			pQueueFamilyIndices
3022 			VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
3023 		};
3024 
3025 		checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);
3026 
3027 		resultImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
3028 		resultImageAllocation = m_context.getDefaultAllocator().allocate(getImageMemoryRequirements(vkd, device, *resultImage), MemoryRequirement::Any);
3029 		VK_CHECK(vkd.bindImageMemory(device, *resultImage, resultImageAllocation->getMemory(), resultImageAllocation->getOffset()));
3030 	}
3031 
3032 	// Initialize color image. This is expected to be cleared later.
3033 	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);
3034 	// Initialize result image. This will be overwritten later.
3035 	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);
3036 
3037 	// Create image views.
3038 	{
3039 		const VkImageViewCreateInfo imageViewCreateInfo =
3040 		{
3041 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType
3042 			DE_NULL,									// const void*				pNext
3043 			0u,											// VkImageViewCreateFlags	flags
3044 			*colorImage,								// VkImage					image
3045 			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType
3046 			m_format,									// VkFormat					format
3047 			makeComponentMappingRGBA(),					// VkComponentMapping		components
3048 			{											// VkImageSubresourceRange	subresourceRange
3049 				VK_IMAGE_ASPECT_COLOR_BIT,
3050 				0u,
3051 				1u,
3052 				0u,
3053 				1u
3054 			}
3055 		};
3056 
3057 		imageViewInput = createImageView(vkd, device, &imageViewCreateInfo);
3058 	}
3059 
3060 	{
3061 		const VkImageViewCreateInfo imageViewCreateInfo =
3062 		{
3063 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType
3064 			DE_NULL,									// const void*				pNext
3065 			0u,											// VkImageViewCreateFlags	flags
3066 			*resultImage,								// VkImage					image
3067 			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType
3068 			m_format,									// VkFormat					format
3069 			makeComponentMappingRGBA(),					// VkComponentMapping		components
3070 			{											// VkImageSubresourceRange	subresourceRange
3071 				VK_IMAGE_ASPECT_COLOR_BIT,
3072 				0u,
3073 				1u,
3074 				0u,
3075 				1u
3076 			}
3077 		};
3078 
3079 		imageViewResult = createImageView(vkd, device, &imageViewCreateInfo);
3080 	}
3081 
3082 	// Create result buffer.
3083 	{
3084 		resultBuffer		= createBuffer(vkd, device, m_format, m_width, m_height);
3085 		resultBufferMemory	= createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *resultBuffer);
3086 	}
3087 
3088 	// Create sampler.
3089 	{
3090 		const VkSamplerCreateInfo samplerInfo =
3091 		{
3092 			VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,		// VkStructureType			sType
3093 			DE_NULL,									// const void*				pNext
3094 			0u,											// VkSamplerCreateFlags		flags
3095 			VK_FILTER_NEAREST,							// VkFilter					magFilter
3096 			VK_FILTER_NEAREST,							// VkFilter					minFilter
3097 			VK_SAMPLER_MIPMAP_MODE_NEAREST,				// VkSamplerMipmapMode		mipmapMode
3098 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeU
3099 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeV
3100 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeW
3101 			0.0f,										// float					mipLodBias
3102 			VK_FALSE,									// VkBool32					anisotropyEnable
3103 			1.0f,										// float					maxAnisotropy
3104 			VK_FALSE,									// VkBool32					compareEnable
3105 			VK_COMPARE_OP_ALWAYS,						// VkCompareOp				compareOp
3106 			0.0f,										// float					minLod
3107 			0.0f,										// float					maxLod
3108 			VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,	// VkBorderColor			borderColor
3109 			VK_FALSE,									// VkBool32					unnormalizedCoordinates
3110 		};
3111 
3112 		sampler = createSampler(vkd, device, &samplerInfo);
3113 	}
3114 
3115 	// Create descriptor set layouts.
3116 	Unique<VkDescriptorSetLayout>	descriptorSetLayoutInput	(DescriptorSetLayoutBuilder()
3117 			.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
3118 			.build(vkd, device));
3119 
3120 	Unique<VkDescriptorSetLayout>	descriptorSetLayoutImageSampler	(DescriptorSetLayoutBuilder()
3121 			.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT)
3122 			.build(vkd, device));
3123 
3124 	// Create descriptor pool.
3125 	Unique<VkDescriptorPool>		descriptorPool		(DescriptorPoolBuilder()
3126 			.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u)
3127 			.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1u)
3128 			.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 2u));
3129 
3130 	// Create desriptor sets.
3131 	Unique<VkDescriptorSet>			descriptorSetInput	(makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayoutInput));
3132 	Unique<VkDescriptorSet>			descriptorSetImageSampler	(makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayoutImageSampler));
3133 
3134 	// Update descriptor set information.
3135 	VkDescriptorImageInfo			descIOAttachment	= makeDescriptorImageInfo(DE_NULL, *imageViewInput, VK_IMAGE_LAYOUT_GENERAL);
3136 	VkDescriptorImageInfo			descImageSampler	= makeDescriptorImageInfo(*sampler, *imageViewInput, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
3137 
3138 	DescriptorSetUpdateBuilder()
3139 		.writeSingle(*descriptorSetInput, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descIOAttachment)
3140 		.update(vkd, device);
3141 
3142 	DescriptorSetUpdateBuilder()
3143 		.writeSingle(*descriptorSetImageSampler, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descImageSampler)
3144 		.update(vkd, device);
3145 
3146 	// Create pipeline layouts.
3147 	{
3148 		const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
3149 		{
3150 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType
3151 			DE_NULL,										// const void*					pNext
3152 			(vk::VkPipelineLayoutCreateFlags)0,				// VkPipelineLayoutCreateFlags	flags
3153 			1u,												// deUint32						setLayoutCount
3154 			&descriptorSetLayoutInput.get(),				// const VkDescriptorSetLayout*	pSetLayouts
3155 			0u,												// deUint32						pushConstantRangeCount
3156 			DE_NULL											// const VkPushConstantRange*	pPushConstantRanges
3157 		};
3158 
3159 		pipelineLayoutInput = createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
3160 	}
3161 	{
3162 		const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
3163 		{
3164 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType
3165 			DE_NULL,										// const void*					pNext
3166 			(vk::VkPipelineLayoutCreateFlags)0,				// VkPipelineLayoutCreateFlags	flags
3167 			1u,												// deUint32						setLayoutCount
3168 			&descriptorSetLayoutImageSampler.get(),			// const VkDescriptorSetLayout*	pSetLayouts
3169 			0u,												// deUint32						pushConstantRangeCount
3170 			DE_NULL											// const VkPushConstantRange*	pPushConstantRanges
3171 		};
3172 
3173 		pipelineLayoutImageSampler = createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
3174 	}
3175 
3176 	// Create render passes.
3177 	{
3178 		vector<Attachment>			attachments;
3179 		vector<AttachmentReference>	colorAttachmentReferences;
3180 
3181 		attachments.push_back(Attachment(m_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
3182 										 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
3183 										 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
3184 
3185 		colorAttachmentReferences.push_back(AttachmentReference(0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
3186 
3187 		const vector<Subpass>			subpasses	(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
3188 													 colorAttachmentReferences, vector<AttachmentReference>(),
3189 													 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<deUint32>()));
3190 
3191 		renderPass1 = createRenderPass(vkd, device, RenderPass(attachments, subpasses, vector<SubpassDependency>()), m_renderingType);
3192 	}
3193 	{
3194 		vector<Attachment>			attachments;
3195 		vector<AttachmentReference>	colorAttachmentReferences;
3196 		vector<AttachmentReference>	inputAttachmentReferences;
3197 
3198 		const VkImageAspectFlags	inputAttachmentAspectMask	((m_renderingType == RENDERING_TYPE_RENDERPASS2)
3199 																? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT)
3200 																: static_cast<VkImageAspectFlags>(0));
3201 
3202 		attachments.push_back(Attachment(m_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
3203 										 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL));
3204 
3205 		colorAttachmentReferences.push_back(AttachmentReference(0u, VK_IMAGE_LAYOUT_GENERAL));
3206 		inputAttachmentReferences.push_back(AttachmentReference(0u, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask));
3207 
3208 		const vector<Subpass>			subpasses		(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, inputAttachmentReferences,
3209 														 colorAttachmentReferences, vector<AttachmentReference>(),
3210 														 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<deUint32>()));
3211 
3212 		const vector<SubpassDependency>	dependencies	(1, SubpassDependency(0u, 0u, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
3213 														 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
3214 														 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, VK_DEPENDENCY_BY_REGION_BIT));
3215 
3216 		renderPass0 = createRenderPass(vkd, device, RenderPass(attachments, subpasses, dependencies), m_renderingType);
3217 	}
3218 
3219 	// Create pipelines.
3220 	{
3221 		const Unique<VkShaderModule>				vertexShaderModule				(createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u));
3222 		const Unique<VkShaderModule>				fragmentShaderModuleInputAtt	(createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag_input_attachment"), 0u));
3223 		const Unique<VkShaderModule>				fragmentShaderModuleSolidColor	(createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag_solid_color"), 0u));
3224 		const Unique<VkShaderModule>				fragmentShaderModuleSampler		(createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag_combined_image_sampler"), 0u));
3225 
3226 		const VkVertexInputBindingDescription		vertexBinding0					=
3227 		{
3228 			0u,							// deUint32					binding
3229 			sizeof(Vec4),				// deUint32					strideInBytes
3230 			VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputStepRate	stepRate
3231 		};
3232 
3233 		const VkVertexInputAttributeDescription		attr0							=
3234 		{
3235 			0u,								// deUint32	location
3236 			0u,								// deUint32	binding
3237 			VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format
3238 			0u								// deUint32	offsetInBytes
3239 		};
3240 
3241 		const VkPipelineVertexInputStateCreateInfo	vertexInputState				=
3242 		{
3243 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType
3244 			DE_NULL,													// const void*								pNext
3245 			(VkPipelineVertexInputStateCreateFlags)0u,					// VkPipelineVertexInputStateCreateFlags	flags
3246 			1u,															// deUint32									vertexBindingDescriptionCount
3247 			&vertexBinding0,											// const VkVertexInputBindingDescription*	pVertexBindingDescriptions
3248 			1u,															// deUint32									vertexAttributeDescriptionCount
3249 			&attr0														// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions
3250 		};
3251 
3252 		const std::vector<VkViewport>				viewports						(1, makeViewport(tcu::UVec2(m_width, m_height)));
3253 		const std::vector<VkRect2D>					scissors						(1, makeRect2D(tcu::UVec2(m_width, m_height)));
3254 
3255 		const VkPipelineColorBlendAttachmentState		colorBlendAttachmentState	=
3256 		{
3257 			VK_TRUE,								// VkBool32					blendEnable
3258 			VK_BLEND_FACTOR_ONE,					// VkBlendFactor			srcColorBlendFactor
3259 			VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,	// VkBlendFactor			dstColorBlendFactor
3260 			VK_BLEND_OP_ADD,						// VkBlendOp				colorBlendOp
3261 			VK_BLEND_FACTOR_ONE,					// VkBlendFactor			srcAlphaBlendFactor
3262 			VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,	// VkBlendFactor			dstAlphaBlendFactor
3263 			VK_BLEND_OP_ADD,						// VkBlendOp				alphaBlendOp
3264 			VK_COLOR_COMPONENT_R_BIT				// VkColorComponentFlags	colorWriteMask
3265 				| VK_COLOR_COMPONENT_G_BIT
3266 				| VK_COLOR_COMPONENT_B_BIT
3267 				| VK_COLOR_COMPONENT_A_BIT
3268 		};
3269 
3270 		const VkPipelineColorBlendStateCreateInfo		colorBlendState				=
3271 		{
3272 			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType
3273 			DE_NULL,													// const void*									pNext
3274 			0u,															// VkPipelineColorBlendStateCreateFlags			flags
3275 			VK_FALSE,													// VkBool32										logicOpEnable
3276 			VK_LOGIC_OP_CLEAR,											// VkLogicOp									logicOp
3277 			1u,															// deUint32										attachmentCount
3278 			&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments
3279 			{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4]
3280 		};
3281 
3282 		pipelineSolidColor = makeGraphicsPipeline(vkd,		// const DeviceInterface&							vk
3283 				device,										// const VkDevice									device
3284 				*pipelineLayoutInput,						// const VkPipelineLayout							pipelineLayout
3285 				*vertexShaderModule,						// const VkShaderModule								vertexShaderModule
3286 				DE_NULL,									// const VkShaderModule								tessellationControlShaderModule
3287 				DE_NULL,									// const VkShaderModule								tessellationEvalShaderModule
3288 				DE_NULL,									// const VkShaderModule								geometryShaderModule
3289 				*fragmentShaderModuleSolidColor,			// const VkShaderModule								fragmentShaderModule
3290 				*renderPass0,								// const VkRenderPass								renderPass
3291 				viewports,									// const std::vector<VkViewport>&					viewports
3292 				scissors,									// const std::vector<VkRect2D>&						scissors
3293 				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,		// const VkPrimitiveTopology						topology
3294 				0u,											// const deUint32									subpass
3295 				0u,											// const deUint32									patchControlPoints
3296 				&vertexInputState,							// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
3297 				DE_NULL,									// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
3298 				DE_NULL,									// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
3299 				DE_NULL,									// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
3300 				&colorBlendState);							// const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo
3301 
3302 		pipelineInputAtt = makeGraphicsPipeline(vkd,		// const DeviceInterface&							vk
3303 				device,										// const VkDevice									device
3304 				*pipelineLayoutInput,						// const VkPipelineLayout							pipelineLayout
3305 				*vertexShaderModule,						// const VkShaderModule								vertexShaderModule
3306 				DE_NULL,									// const VkShaderModule								tessellationControlShaderModule
3307 				DE_NULL,									// const VkShaderModule								tessellationEvalShaderModule
3308 				DE_NULL,									// const VkShaderModule								geometryShaderModule
3309 				*fragmentShaderModuleInputAtt,				// const VkShaderModule								fragmentShaderModule
3310 				*renderPass0,								// const VkRenderPass								renderPass
3311 				viewports,									// const std::vector<VkViewport>&					viewports
3312 				scissors,									// const std::vector<VkRect2D>&						scissors
3313 				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,		// const VkPrimitiveTopology						topology
3314 				0u,											// const deUint32									subpass
3315 				0u,											// const deUint32									patchControlPoints
3316 				&vertexInputState,							// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
3317 				DE_NULL,									// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
3318 				DE_NULL,									// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
3319 				DE_NULL,									// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
3320 				&colorBlendState);							// const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo
3321 
3322 		pipelineImageSampler = makeGraphicsPipeline(vkd,	// const DeviceInterface&							vk
3323 				device,										// const VkDevice									device
3324 				*pipelineLayoutImageSampler,				// const VkPipelineLayout							pipelineLayout
3325 				*vertexShaderModule,						// const VkShaderModule								vertexShaderModule
3326 				DE_NULL,									// const VkShaderModule								tessellationControlShaderModule
3327 				DE_NULL,									// const VkShaderModule								tessellationEvalShaderModule
3328 				DE_NULL,									// const VkShaderModule								geometryShaderModule
3329 				*fragmentShaderModuleSampler,				// const VkShaderModule								fragmentShaderModule
3330 				*renderPass1,								// const VkRenderPass								renderPass
3331 				viewports,									// const std::vector<VkViewport>&					viewports
3332 				scissors,									// const std::vector<VkRect2D>&						scissors
3333 				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,		// const VkPrimitiveTopology						topology
3334 				0u,											// const deUint32									subpass
3335 				0u,											// const deUint32									patchControlPoints
3336 				&vertexInputState,							// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
3337 				DE_NULL,									// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
3338 				DE_NULL,									// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
3339 				DE_NULL,									// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
3340 				&colorBlendState);							// const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo
3341 	}
3342 
3343 	// Create framebuffers.
3344 	{
3345 		const VkFramebufferCreateInfo	framebufferCreateInfo	=
3346 		{
3347 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType
3348 			DE_NULL,									// const void*				pNext
3349 			0u,											// VkFramebufferCreateFlags	flags
3350 			*renderPass0,								// VkRenderPass				renderPass
3351 			1u,											// uint32_t					attachmentCount
3352 			&imageViewInput.get(),						// const VkImageView*		pAttachments
3353 			256u,										// uint32_t					width
3354 			256u,										// uint32_t					height
3355 			1u											// uint32_t					layers
3356 		};
3357 
3358 		framebuffer0 = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
3359 	}
3360 	{
3361 		const VkFramebufferCreateInfo	framebufferCreateInfo	=
3362 		{
3363 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType
3364 			DE_NULL,									// const void*				pNext
3365 			0u,											// VkFramebufferCreateFlags	flags
3366 			*renderPass1,								// VkRenderPass				renderPass
3367 			1u,											// uint32_t					attachmentCount
3368 			&imageViewResult.get(),						// const VkImageView*		pAttachments
3369 			m_width,									// uint32_t					width
3370 			m_height,									// uint32_t					height
3371 			1u											// uint32_t					layers
3372 		};
3373 
3374 		framebuffer1 = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
3375 	}
3376 
3377 	// Generate quad vertices.
3378 	{
3379 		const tcu::Vec4	lowerLeftVertex		(-1.0f, -1.0f, 0.5f, 1.0f);
3380 		const tcu::Vec4	lowerRightVertex	(1.0f, -1.0f, 0.5f, 1.0f);
3381 		const tcu::Vec4	upperLeftVertex		(-1.0f, 1.0f, 0.5f, 1.0f);
3382 		const tcu::Vec4	upperRightVertex	(1.0f, 1.0f, 0.5f, 1.0f);
3383 
3384 		vertexData.push_back(lowerLeftVertex);
3385 		vertexData.push_back(upperLeftVertex);
3386 		vertexData.push_back(lowerRightVertex);
3387 		vertexData.push_back(upperRightVertex);
3388 	}
3389 
3390 	// Upload vertex data.
3391 	{
3392 		const size_t				vertexDataSize		= vertexData.size() * sizeof(Vec4);
3393 
3394 		const VkBufferCreateInfo	vertexBufferParams	=
3395 		{
3396 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	//	VkStructureType		sType
3397 			DE_NULL,								//	const void*			pNext
3398 			0u,										//	VkBufferCreateFlags	flags
3399 			(VkDeviceSize)vertexDataSize,			//	VkDeviceSize		size
3400 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		//	VkBufferUsageFlags	usage
3401 			VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode		sharingMode
3402 			1u,										//	deUint32			queueFamilyCount
3403 			&queueFamilyIndex,						//	const deUint32*		pQueueFamilyIndices
3404 		};
3405 
3406 		vertexBuffer		= createBuffer(vkd, m_context.getDevice(), &vertexBufferParams);
3407 		vertexBufferMemory	= createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *vertexBuffer);
3408 
3409 		deMemcpy(vertexBufferMemory->getHostPtr(), vertexData.data(), vertexDataSize);
3410 		flushAlloc(vkd, device, *vertexBufferMemory);
3411 	}
3412 
3413 	beginCommandBuffer(vkd, *commandBuffer);
3414 
3415 	// Begin render pass.
3416 	{
3417 		const VkRect2D				renderArea	=
3418 		{
3419 			{ 0u, 0u },				// VkOffset2D	offset
3420 			{ m_width, m_height }	// VkExtent2D	extent
3421 		};
3422 
3423 		const VkClearValue			clearValue	= makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 0.0f));
3424 
3425 		const VkRenderPassBeginInfo	beginInfo	=
3426 		{
3427 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType
3428 			DE_NULL,									// const void*			pNext
3429 			*renderPass0,								// VkRenderPass			renderPass
3430 			*framebuffer0,								// VkFramebuffer		framebuffer
3431 			renderArea,									// VkRect2D				renderArea
3432 			1u,											// uint32_t				clearValueCount
3433 			&clearValue									// const VkClearValue*	pClearValues
3434 		};
3435 
3436 		RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
3437 	}
3438 
3439 	// Bind pipeline.
3440 	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineSolidColor);
3441 
3442 	// Bind vertex buffer.
3443 	const VkDeviceSize bindingOffset = 0;
3444 	vkd.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
3445 
3446 	// Bind descriptor set.
3447 	vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayoutInput, 0u, 1u, &*descriptorSetInput, 0u, DE_NULL);
3448 
3449 	// Draw solid color.
3450 	vkd.cmdDraw(*commandBuffer, 4u, 1u, 0u, 0u);
3451 
3452 	// Bind pipeline.
3453 	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineInputAtt);
3454 
3455 	// Bind descriptor set.
3456 	vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayoutInput, 0u, 1u, &*descriptorSetInput, 0u, DE_NULL);
3457 
3458 	// Pipeline barrier to handle self dependency.
3459 	{
3460 		const VkImageMemoryBarrier imageBarrier =
3461 		{
3462 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType
3463 			DE_NULL,										// const void*				pNext
3464 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			srcAccessMask
3465 			VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,			// VkAccessFlags			dstAccessMask
3466 			VK_IMAGE_LAYOUT_GENERAL,						// VkImageLayout			oldLayout
3467 			VK_IMAGE_LAYOUT_GENERAL,						// VkImageLayout			newLayout
3468 			VK_QUEUE_FAMILY_IGNORED,						// uint32_t					srcQueueFamilyIndex
3469 			VK_QUEUE_FAMILY_IGNORED,						// uint32_t					dstQueueFamilyIndex
3470 			*colorImage,									// VkImage					image
3471 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange
3472 		};
3473 
3474 		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);
3475 	}
3476 
3477 	// Draw. Adds (0.1, 0.2, 0.0, 0.0) to the previous result.
3478 	vkd.cmdDraw(*commandBuffer, 4u, 1u, 0u, 0u);
3479 
3480 	// End render pass.
3481 	RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
3482 
3483 	// Pipeline barrier.
3484 	{
3485 		const VkImageMemoryBarrier imageBarriers[] =
3486 		{
3487 			{
3488 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType
3489 				DE_NULL,										// const void*				pNext
3490 				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
3491 				| VK_ACCESS_TRANSFER_WRITE_BIT
3492 				| VK_ACCESS_HOST_WRITE_BIT,						// VkAccessFlags			srcAccessMask
3493 				VK_ACCESS_SHADER_READ_BIT,						// VkAccessFlags			dstAccessMask
3494 				VK_IMAGE_LAYOUT_GENERAL,						// VkImageLayout			oldLayout
3495 				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,		// VkImageLayout			newLayout
3496 				VK_QUEUE_FAMILY_IGNORED,						// uint32_t					srcQueueFamilyIndex
3497 				VK_QUEUE_FAMILY_IGNORED,						// uint32_t					dstQueueFamilyIndex
3498 				*colorImage,									// VkImage					image
3499 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange
3500 			},
3501 			{
3502 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType
3503 				DE_NULL,										// const void*				pNext
3504 				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			srcAccessMask
3505 				VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
3506 				| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask
3507 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			oldLayout
3508 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout
3509 				VK_QUEUE_FAMILY_IGNORED,						// uint32_t					srcQueueFamilyIndex
3510 				VK_QUEUE_FAMILY_IGNORED,						// uint32_t					dstQueueFamilyIndex
3511 				*resultImage,									// VkImage					image
3512 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange
3513 			}
3514 		};
3515 
3516 		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);
3517 	}
3518 
3519 	// Begin render pass.
3520 	{
3521 		const VkRect2D				renderArea	=
3522 		{
3523 			{ 0, 0 },	            // VkOffset2D	offset
3524 			{ m_width, m_height }	// VkExtent2D	extent
3525 		};
3526 
3527 		const VkRenderPassBeginInfo	beginInfo	=
3528 		{
3529 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType
3530 			DE_NULL,									// const void*			pNext
3531 			*renderPass1,								// VkRenderPass			renderPass
3532 			*framebuffer1,								// VkFramebuffer		framebuffer
3533 			renderArea,									// VkRect2D				renderArea
3534 			0u,											// uint32_t				clearValueCount
3535 			DE_NULL										// const VkClearValue*	pClearValues
3536 		};
3537 
3538 		RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
3539 	}
3540 
3541 	// Bind pipeline.
3542 	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineImageSampler);
3543 
3544 	// Bind descriptor set.
3545 	vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayoutImageSampler, 0u, 1u, &*descriptorSetImageSampler, 0u, DE_NULL);
3546 
3547 	// Draw. Samples the previous results and adds (0.1, 0.2, 0.0, 0.0).
3548 	vkd.cmdDraw(*commandBuffer, 4u, 1u, 0u, 0u);
3549 
3550 	// End render pass.
3551 	RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
3552 
3553 	// Copy results to a buffer.
3554 	copyImageToBuffer(vkd, *commandBuffer, *resultImage, *resultBuffer, tcu::IVec2(m_width, m_height), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
3555 
3556 	endCommandBuffer(vkd, *commandBuffer);
3557 	submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
3558 	invalidateMappedMemoryRange(vkd, m_context.getDevice(), resultBufferMemory->getMemory(), resultBufferMemory->getOffset(), VK_WHOLE_SIZE);
3559 
3560 	// Verify results.
3561 	{
3562 		const tcu::TextureFormat			format			(mapVkFormat(m_format));
3563 		tcu::TextureLevel					reference		(format, m_width, m_height);
3564 		const void* const					ptrResult		(resultBufferMemory->getHostPtr());
3565 		const tcu::ConstPixelBufferAccess	resultAccess	(format, m_width, m_height, 1, ptrResult);
3566 		const PixelBufferAccess				referenceAccess	(reference.getAccess());
3567 
3568 		for (deUint32 x = 0; x < m_width; x++)
3569 			for (deUint32 y = 0; y < m_height; y++)
3570 			{
3571 				referenceAccess.setPixel(tcu::Vec4(0.3f, 0.6f, 0.0f, 1.0f), x, y, 0);
3572 			}
3573 
3574 		if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(),	// log
3575 										"Rendered result",						// imageSetName
3576 										"",										// imageSetDesc
3577 										referenceAccess,						// reference
3578 										resultAccess,							// result
3579 										Vec4(0.05f),							// threshold
3580 										tcu::COMPARE_LOG_RESULT))				// logMode
3581 		{
3582 			m_resultCollector.fail("Image compare failed.");
3583 		}
3584 	}
3585 
3586 	return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
3587 }
3588 
3589 // Shader programs for testing dependencies between render pass instances
3590 struct ExternalPrograms
3591 {
initvkt::__anonaf246e430111::ExternalPrograms3592 	void init (vk::SourceCollections& dst, ExternalTestConfig testConfig) const
3593 	{
3594 		for (size_t renderPassNdx = 0; renderPassNdx < testConfig.renderPasses.size(); renderPassNdx++)
3595 		{
3596 			dst.glslSources.add("quad-vert-" + de::toString(renderPassNdx)) << glu::VertexSource(
3597 				"#version 450\n"
3598 				"layout(location = 0) out highp vec2 vtxTexCoords;\n"
3599 				"highp float;\n"
3600 				"void main (void)\n"
3601 				"{\n"
3602 				"    vec4 position;"
3603 				"    position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
3604 				"                    ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
3605 				"    gl_Position = position;\n"
3606 				"	vtxTexCoords = position.xy / 2.0 + vec2(0.5);"
3607 				"}\n");
3608 
3609 			// First pass renders four quads of different color
3610 			if (renderPassNdx == 0)
3611 			{
3612 				dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
3613 					"#version 450\n"
3614 					"layout(location = 0) in highp vec2 vtxTexCoords;\n"
3615 					"layout(location = 0) out highp vec4 o_color;\n"
3616 					"void main (void)\n"
3617 					"{\n"
3618 					"    if (gl_FragCoord.x <= " + de::toString(testConfig.imageSize.x() / 2) + " && gl_FragCoord.y <= " + de::toString(testConfig.imageSize.y() / 2) + ")\n"
3619 					"        o_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
3620 					"    else if (gl_FragCoord.x > " + de::toString(testConfig.imageSize.x() / 2) + " && gl_FragCoord.y <= " + de::toString(testConfig.imageSize.y() / 2) + ")\n"
3621 					"        o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
3622 					"    else if (gl_FragCoord.x <= " + de::toString(testConfig.imageSize.x() / 2) + " && gl_FragCoord.y > " + de::toString(testConfig.imageSize.y() / 2) + ")\n"
3623 					"        o_color = vec4(0.0, 0.0, 1.0, 1.0);\n"
3624 					"    else\n"
3625 					"        o_color = vec4(0.0, 0.0, 0.0, 1.0);\n"
3626 					""
3627 					"}\n");
3628 			}
3629 			else
3630 			{
3631 				if (renderPassNdx % 2 == 0)
3632 				{
3633 					// Blur previous pass horizontally
3634 					dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
3635 						"#version 450\n"
3636 						"layout(binding = 0) uniform sampler2D previousPass;\n"
3637 						"layout(location = 0) in highp vec2 vtxTexCoords;\n"
3638 						"layout(location = 0) out highp vec4 o_color;\n"
3639 						"void main (void)\n"
3640 						"{\n"
3641 						"    vec2 step = vec2(1.0 / " + de::toString(testConfig.imageSize.x()) + ", 1.0 / " + de::toString(testConfig.imageSize.y()) + ");\n"
3642 						"    vec2 minCoord = vec2(0.0, 0.0);\n"
3643 						"    vec2 maxCoord = vec2(1.0, 1.0);\n"
3644 						"    vec4 blurColor = vec4(0.0);\n"
3645 						"    for(int sampleNdx = 0; sampleNdx < " + de::toString(testConfig.blurKernel + 1) + "; sampleNdx++)\n"
3646 						"    {\n"
3647 						"        vec2 sampleCoord = vec2((vtxTexCoords.x - " + de::toString(testConfig.blurKernel / 2) + " * step.x) + step.x * sampleNdx, vtxTexCoords.y);\n"
3648 						"        blurColor += 0.12 * texture(previousPass, clamp(sampleCoord, minCoord, maxCoord));\n"
3649 						"    }\n"
3650 						"    o_color = blurColor;\n"
3651 						"}\n");
3652 				}
3653 				else
3654 				{
3655 					// Blur previous pass vertically
3656 					dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
3657 						"#version 450\n"
3658 						"layout(binding = 0) uniform highp sampler2D previousPass;\n"
3659 						"layout(location = 0) in highp vec2 vtxTexCoords;\n"
3660 						"layout(location = 0) out highp vec4 o_color;\n"
3661 						"void main (void)\n"
3662 						"{\n"
3663 						"    vec2 step = vec2(1.0 / " + de::toString(testConfig.imageSize.x()) + ", 1.0 / " + de::toString(testConfig.imageSize.y()) + ");\n"
3664 						"    vec2 minCoord = vec2(0.0, 0.0);\n"
3665 						"    vec2 maxCoord = vec2(1.0, 1.0);\n"
3666 						"    vec4 blurColor = vec4(0.0);\n"
3667 						"    for(int sampleNdx = 0; sampleNdx < " + de::toString(testConfig.blurKernel + 1) + "; sampleNdx++)\n"
3668 						"    {\n"
3669 						"        vec2 sampleCoord = vec2(vtxTexCoords.x, (vtxTexCoords.y - " + de::toString(testConfig.blurKernel / 2) + " * step.y) + step.y * sampleNdx);\n"
3670 						"        blurColor += 0.12 * texture(previousPass, clamp(sampleCoord, minCoord, maxCoord));\n"
3671 						"    }\n"
3672 						"    o_color = blurColor;\n"
3673 						"}\n");
3674 				}
3675 			}
3676 		}
3677 	}
3678 };
3679 
3680 // Shader programs for testing dependencies between subpasses
3681 struct SubpassPrograms
3682 {
initvkt::__anonaf246e430111::SubpassPrograms3683 	void init (vk::SourceCollections& dst, SubpassTestConfig testConfig) const
3684 	{
3685 		size_t subpassCount = testConfig.renderPass.getSubpasses().size();
3686 
3687 		for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
3688 		{
3689 			if (subpassNdx == 0)
3690 			{
3691 				dst.glslSources.add("subpass-vert-" + de::toString(subpassNdx)) << glu::VertexSource(
3692 				"#version 450\n"
3693 				"highp float;\n"
3694 				"layout(location = 0) in highp vec4 position;\n"
3695 				"void main (void)\n"
3696 				"{\n"
3697 				"    gl_Position = position;\n"
3698 				"}\n");
3699 			}
3700 			else
3701 			{
3702 				dst.glslSources.add("subpass-vert-" + de::toString(subpassNdx)) << glu::VertexSource(
3703 					"#version 450\n"
3704 					"highp float;\n"
3705 					"void main (void)\n"
3706 					"{\n"
3707 					"    vec4 position;"
3708 					"    position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
3709 					"                    ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
3710 					"    gl_Position = position;\n"
3711 					"}\n");
3712 			}
3713 
3714 			if (isDepthStencilFormat(testConfig.format))
3715 			{
3716 				if (subpassNdx == 0)
3717 				{
3718 					// Empty fragment shader: Fragment depth unmodified.
3719 					dst.glslSources.add("subpass-frag-" + de::toString(subpassNdx)) << glu::FragmentSource(
3720 						"#version 450\n"
3721 						"void main (void)\n"
3722 						"{\n"
3723 						"}\n");
3724 				}
3725 				else
3726 				{
3727 					// Use fragment depth from previous depth rendering result.
3728 					dst.glslSources.add("subpass-frag-" + de::toString(subpassNdx)) << glu::FragmentSource(
3729 						"#version 450\n"
3730 						"layout (input_attachment_index = 0, binding = 0) uniform subpassInput depthStencil;\n"
3731 						"void main (void)\n"
3732 						"{\n"
3733 						"    float inputDepth = subpassLoad(depthStencil).x;\n"
3734 						"    gl_FragDepth = inputDepth - 0.02;\n"
3735 						"}\n");
3736 				}
3737 			}
3738 			else
3739 				DE_FATAL("Unimplemented");
3740 		}
3741 	}
3742 };
3743 
3744 // Shader programs for testing backwards subpass self dependency from geometry stage to indirect draw
3745 struct SubpassSelfDependencyBackwardsPrograms
3746 {
initvkt::__anonaf246e430111::SubpassSelfDependencyBackwardsPrograms3747 	void init (vk::SourceCollections& dst, SubpassSelfDependencyBackwardsTestConfig testConfig) const
3748 	{
3749 		DE_UNREF(testConfig);
3750 
3751 		dst.glslSources.add("vert") << glu::VertexSource(
3752 				"#version 450\n"
3753 				"layout(location = 0) in highp vec4 position;\n"
3754 				"out gl_PerVertex {\n"
3755 				"    vec4 gl_Position;\n"
3756 				"};\n"
3757 				"void main (void)\n"
3758 				"{\n"
3759 				"    gl_Position = position;\n"
3760 				"}\n");
3761 
3762 		dst.glslSources.add("geom") << glu::GeometrySource(
3763 				"#version 450\n"
3764 				"layout(points) in;\n"
3765 				"layout(triangle_strip, max_vertices = 4) out;\n"
3766 				"\n"
3767 				"in gl_PerVertex {\n"
3768 				"    vec4 gl_Position;\n"
3769 				"} gl_in[];\n"
3770 				"\n"
3771 				"out gl_PerVertex {\n"
3772 				"    vec4 gl_Position;\n"
3773 				"};\n"
3774 				"layout (binding = 0) buffer IndirectBuffer\n"
3775 				"{\n"
3776 				"    uint vertexCount;\n"
3777 				"    uint instanceCount;\n"
3778 				"    uint firstVertex;\n"
3779 				"    uint firstInstance;\n"
3780 				"} indirectBuffer;\n"
3781 				"\n"
3782 				"void main (void) {\n"
3783 				"    vec4 p = gl_in[0].gl_Position;\n"
3784 				"    float offset = 0.03f;\n"
3785 				"    gl_Position = p + vec4(-offset, offset, 0, 0);\n"
3786 				"    EmitVertex();\n"
3787 				"    gl_Position = p + vec4(-offset, -offset, 0, 0);\n"
3788 				"    EmitVertex();\n"
3789 				"    gl_Position = p + vec4(offset, offset, 0, 0);\n"
3790 				"    EmitVertex();\n"
3791 				"    gl_Position = p + vec4(offset, -offset, 0, 0);\n"
3792 				"    EmitVertex();\n"
3793 				"    EndPrimitive();\n"
3794 				"    indirectBuffer.vertexCount = 64;\n"
3795 				"    indirectBuffer.instanceCount = 1;\n"
3796 				"    indirectBuffer.firstVertex = 64;\n"
3797 				"    indirectBuffer.firstInstance = 0;\n"
3798 				"}\n");
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, 0, 0, 1);\n"
3806 				"}\n");
3807 	}
3808 };
3809 
3810 struct SeparateChannelsPrograms
3811 {
initvkt::__anonaf246e430111::SeparateChannelsPrograms3812 	void init (vk::SourceCollections& dst, SeparateChannelsTestConfig testConfig) const
3813 	{
3814 		dst.glslSources.add("vert") << glu::VertexSource(
3815 				"#version 450\n"
3816 				"layout(location = 0) in highp vec4 position;\n"
3817 				"void main (void)\n"
3818 				"{\n"
3819 				"    gl_Position = position;\n"
3820 				"}\n");
3821 
3822 		if (isDepthStencilFormat(testConfig.format))
3823 		{
3824 			dst.glslSources.add("frag") << glu::FragmentSource(
3825 					"#version 450\n"
3826 					"layout(location = 0) out highp vec4 fragColor;\n"
3827 					"void main (void)\n"
3828 					"{\n"
3829 					"    fragColor = vec4(1);\n"
3830 					"}\n");
3831 		}
3832 		else
3833 		{
3834 			dst.glslSources.add("frag") << glu::FragmentSource(
3835 					"#version 450\n"
3836 					"layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInput inputAtt;\n"
3837 					"layout(location = 0) out highp vec4 fragColor;\n"
3838 					"void main (void)\n"
3839 					"{\n"
3840 					"    vec4 inputColor = subpassLoad(inputAtt);\n"
3841 					"    fragColor = vec4(1, 1, inputColor.r + inputColor.g, 1);\n"
3842 					"}\n");
3843 		}
3844 	}
3845 };
3846 
3847 struct SingleAttachmentPrograms
3848 {
initvkt::__anonaf246e430111::SingleAttachmentPrograms3849 	void init (vk::SourceCollections& dst, SingleAttachmentTestConfig testConfig) const
3850 	{
3851 		DE_UNREF(testConfig);
3852 
3853 		dst.glslSources.add("vert") << glu::VertexSource(
3854 				"#version 450\n"
3855 				"layout(location = 0) in highp vec4 position;\n"
3856 				"void main (void)\n"
3857 				"{\n"
3858 				"    gl_Position = position;\n"
3859 				"}\n");
3860 
3861 		dst.glslSources.add("frag_solid_color") << glu::FragmentSource(
3862 				"#version 450\n"
3863 				"layout(location = 0) out highp vec4 fragColor;\n"
3864 				"void main (void)\n"
3865 				"{\n"
3866 				"    fragColor = vec4(0.1, 0.2, 0.0, 1.0);\n"
3867 				"}\n");
3868 
3869 		dst.glslSources.add("frag_input_attachment") << glu::FragmentSource(
3870 				"#version 450\n"
3871 				"layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInput inputAtt;\n"
3872 				"layout(location = 0) out highp vec4 fragColor;\n"
3873 				"void main (void)\n"
3874 				"{\n"
3875 				"    vec4 inputColor = subpassLoad(inputAtt);\n"
3876 				"    fragColor = inputColor + vec4(0.1, 0.2, 0.0, 0.0);\n"
3877 				"}\n");
3878 
3879 		dst.glslSources.add("frag_combined_image_sampler") << glu::FragmentSource(
3880 				"#version 450\n"
3881 				"layout(set = 0, binding = 0) uniform highp sampler2D tex;\n"
3882 				"layout(location = 0) out highp vec4 fragColor;\n"
3883 				"void main (void)\n"
3884 				"{\n"
3885 				"    vec2 uv = vec2(gl_FragCoord) / 255.0;\n"
3886 				"    vec4 inputColor = texture(tex, uv);\n"
3887 				"    fragColor = inputColor + vec4(0.1, 0.2, 0.0, 0.0);\n"
3888 				"}\n");
3889 	}
3890 };
3891 
formatToName(VkFormat format)3892 std::string formatToName (VkFormat format)
3893 {
3894 	const std::string	formatStr	= de::toString(format);
3895 	const std::string	prefix		= "VK_FORMAT_";
3896 
3897 	DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
3898 
3899 	return de::toLower(formatStr.substr(prefix.length()));
3900 }
3901 
initTests(tcu::TestCaseGroup * group,const RenderingType renderingType)3902 void initTests (tcu::TestCaseGroup* group, const RenderingType renderingType)
3903 {
3904 	tcu::TestContext& testCtx(group->getTestContext());
3905 
3906 	// Test external subpass dependencies
3907 	{
3908 		const deUint32	renderPassCounts[]	= { 2u, 3u, 5u};
3909 
3910 		const UVec2		renderSizes[]		=
3911 		{
3912 			UVec2(64, 64),
3913 			UVec2(128, 128),
3914 			UVec2(512, 512)
3915 		};
3916 
3917 		de::MovePtr<tcu::TestCaseGroup>	externalGroup	(new tcu::TestCaseGroup(testCtx, "external_subpass", "external_subpass"));
3918 
3919 		for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
3920 		{
3921 			string groupName ("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" + de::toString(renderSizes[renderSizeNdx].y()));
3922 			de::MovePtr<tcu::TestCaseGroup> renderSizeGroup	(new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupName.c_str()));
3923 
3924 			for (size_t renderPassCountNdx = 0; renderPassCountNdx < DE_LENGTH_OF_ARRAY(renderPassCounts); renderPassCountNdx++)
3925 			{
3926 				vector<RenderPass>	renderPasses;
3927 
3928 				for (size_t renderPassNdx = 0; renderPassNdx < renderPassCounts[renderPassCountNdx]; renderPassNdx++)
3929 				{
3930 					vector<Attachment>			attachments;
3931 					vector<AttachmentReference>	colorAttachmentReferences;
3932 
3933 					const VkFormat				format				(VK_FORMAT_R8G8B8A8_UNORM);
3934 					const VkSampleCountFlagBits	sampleCount			(VK_SAMPLE_COUNT_1_BIT);
3935 					const VkAttachmentLoadOp	loadOp				(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
3936 					const VkAttachmentStoreOp	storeOp				(VK_ATTACHMENT_STORE_OP_STORE);
3937 					const VkAttachmentLoadOp	stencilLoadOp		(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
3938 					const VkAttachmentStoreOp	stencilStoreOp		(VK_ATTACHMENT_STORE_OP_DONT_CARE);
3939 					const VkImageLayout			initialLayout		(VK_IMAGE_LAYOUT_UNDEFINED);
3940 					const VkImageLayout			finalLayout			(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
3941 					const VkImageLayout			subpassLayout		(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
3942 
3943 					attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalLayout));
3944 					colorAttachmentReferences.push_back(AttachmentReference((deUint32)0, subpassLayout));
3945 
3946 					const VkImageLayout			depthStencilLayout	(VK_IMAGE_LAYOUT_GENERAL);
3947 					const vector<Subpass>		subpasses			(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(),
3948 																		AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<deUint32>()));
3949 					vector<SubpassDependency>	deps;
3950 
3951 					deps.push_back(SubpassDependency(VK_SUBPASS_EXTERNAL,										// deUint32				srcPass
3952 													 0,															// deUint32				dstPass
3953 													 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,				// VkPipelineStageFlags	srcStageMask
3954 													 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,						// VkPipelineStageFlags	dstStageMask
3955 													 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,						// VkAccessFlags		srcAccessMask
3956 													 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,	// VkAccessFlags		dstAccessMask
3957 													 0));														// VkDependencyFlags	flags
3958 
3959 					deps.push_back(SubpassDependency(0,															// deUint32				srcPass
3960 													 VK_SUBPASS_EXTERNAL,										// deUint32				dstPass
3961 													 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,						// VkPipelineStageFlags	srcStageMask
3962 													 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,				// VkPipelineStageFlags	dstStageMask
3963 													 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,	// VkAccessFlags		srcAccessMask
3964 													 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,						// VkAccessFlags		dstAccessMask
3965 													 0));														// VkDependencyFlags	flags
3966 
3967 					RenderPass					renderPass			(attachments, subpasses, deps);
3968 
3969 					renderPasses.push_back(renderPass);
3970 				}
3971 
3972 				const deUint32		blurKernel	(12u);
3973 				string				testName	("render_passes_" + de::toString(renderPassCounts[renderPassCountNdx]));
3974 				ExternalTestConfig	testConfig
3975 				{
3976 					VK_FORMAT_R8G8B8A8_UNORM,
3977 					renderSizes[renderSizeNdx],
3978 					renderPasses,
3979 					renderingType,
3980 					SYNCHRONIZATION_TYPE_LEGACY,
3981 					blurKernel
3982 				};
3983 
3984 				renderSizeGroup->addChild(new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
3985 				if (renderingType == RENDERING_TYPE_RENDERPASS2)
3986 				{
3987 					testName += "_sync_2";
3988 					testConfig.synchronizationType = SYNCHRONIZATION_TYPE_SYNCHRONIZATION2;
3989 					renderSizeGroup->addChild(new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
3990 				}
3991 			}
3992 
3993 			externalGroup->addChild(renderSizeGroup.release());
3994 		}
3995 
3996 		group->addChild(externalGroup.release());
3997 	}
3998 
3999 	// Test implicit subpass dependencies
4000 	{
4001 		const deUint32					renderPassCounts[]		= { 2u, 3u, 5u };
4002 
4003 		de::MovePtr<tcu::TestCaseGroup>	implicitGroup			(new tcu::TestCaseGroup(testCtx, "implicit_dependencies", "implicit_dependencies"));
4004 
4005 		for (size_t renderPassCountNdx = 0; renderPassCountNdx < DE_LENGTH_OF_ARRAY(renderPassCounts); renderPassCountNdx++)
4006 		{
4007 			vector<RenderPass> renderPasses;
4008 
4009 			for (size_t renderPassNdx = 0; renderPassNdx < renderPassCounts[renderPassCountNdx]; renderPassNdx++)
4010 			{
4011 				vector<Attachment>			attachments;
4012 				vector<AttachmentReference>	colorAttachmentReferences;
4013 
4014 				const VkFormat				format					(VK_FORMAT_R8G8B8A8_UNORM);
4015 				const VkSampleCountFlagBits	sampleCount				(VK_SAMPLE_COUNT_1_BIT);
4016 				const VkAttachmentLoadOp	loadOp					(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
4017 				const VkAttachmentStoreOp	storeOp					(VK_ATTACHMENT_STORE_OP_STORE);
4018 				const VkAttachmentLoadOp	stencilLoadOp			(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
4019 				const VkAttachmentStoreOp	stencilStoreOp			(VK_ATTACHMENT_STORE_OP_DONT_CARE);
4020 				const VkImageLayout			initialLayout			(VK_IMAGE_LAYOUT_UNDEFINED);
4021 				const VkImageLayout			finalLayout				(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
4022 				const VkImageLayout			subpassLayout			(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
4023 
4024 				attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalLayout));
4025 				colorAttachmentReferences.push_back(AttachmentReference((deUint32)0, subpassLayout));
4026 
4027 				const VkImageLayout			depthStencilLayout		(VK_IMAGE_LAYOUT_GENERAL);
4028 				const vector<Subpass>		subpasses				(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<deUint32>()));
4029 				vector<SubpassDependency>	deps;
4030 
4031 				// The first render pass lets the implementation add all subpass dependencies implicitly.
4032 				// On the following passes only the dependency from external to first subpass is defined as
4033 				// we need to make sure we have the image ready from previous render pass. In this case
4034 				// the dependency from subpass 0 to external is added implicitly by the implementation.
4035 				if (renderPassNdx > 0)
4036 				{
4037 					deps.push_back(SubpassDependency(VK_SUBPASS_EXTERNAL,										// deUint32				srcPass
4038 													 0,															// deUint32				dstPass
4039 													 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,				// VkPipelineStageFlags	srcStageMask
4040 													 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,						// VkPipelineStageFlags	dstStageMask
4041 													 0,						// VkAccessFlags		srcAccessMask
4042 													 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,	// VkAccessFlags		dstAccessMask
4043 													 0));														// VkDependencyFlags	flags
4044 				}
4045 
4046 				RenderPass					renderPass				(attachments, subpasses, deps);
4047 
4048 				renderPasses.push_back(renderPass);
4049 			}
4050 
4051 			const deUint32				blurKernel	(12u);
4052 			const ExternalTestConfig	testConfig	(VK_FORMAT_R8G8B8A8_UNORM, UVec2(128, 128), renderPasses, renderingType, SYNCHRONIZATION_TYPE_LEGACY, blurKernel);
4053 			const string				testName	("render_passes_" + de::toString(renderPassCounts[renderPassCountNdx]));
4054 
4055 			implicitGroup->addChild(new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
4056 		}
4057 
4058 		group->addChild(implicitGroup.release());
4059 	}
4060 
4061 	// Test late fragment operations using depth_stencil attachments in multipass rendering
4062 	{
4063 		const UVec2		renderSizes[]		=
4064 		{
4065 			UVec2(32, 32),
4066 			UVec2(64, 64),
4067 			UVec2(128, 128)
4068 		};
4069 
4070 		const deUint32	subpassCounts[]		= { 2u, 3u, 5u };
4071 
4072 		// Implementations must support at least one of the following formats
4073 		// for depth_stencil attachments
4074 		const VkFormat formats[]			=
4075 		{
4076 			VK_FORMAT_D24_UNORM_S8_UINT,
4077 			VK_FORMAT_D32_SFLOAT_S8_UINT
4078 		};
4079 
4080 		de::MovePtr<tcu::TestCaseGroup>	lateFragmentTestsGroup (new tcu::TestCaseGroup(testCtx, "late_fragment_tests", "wait for late fragment tests"));
4081 
4082 		for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
4083 		{
4084 			string							renderSizeGroupName	("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" + de::toString(renderSizes[renderSizeNdx].y()));
4085 			de::MovePtr<tcu::TestCaseGroup>	renderSizeGroup		(new tcu::TestCaseGroup(testCtx, renderSizeGroupName.c_str(), renderSizeGroupName.c_str()));
4086 
4087 			for (size_t subpassCountNdx = 0; subpassCountNdx < DE_LENGTH_OF_ARRAY(subpassCounts); subpassCountNdx++)
4088 			{
4089 				string							subpassGroupName	("subpass_count_" + de::toString(subpassCounts[subpassCountNdx]));
4090 				de::MovePtr<tcu::TestCaseGroup>	subpassCountGroup	(new tcu::TestCaseGroup(testCtx, subpassGroupName.c_str(), subpassGroupName.c_str()));
4091 
4092 				for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
4093 				{
4094 					const deUint32				subpassCount	(subpassCounts[subpassCountNdx]);
4095 					const deUint32				attachmentCount	(subpassCount);
4096 					vector<Subpass>				subpasses;
4097 					vector<Attachment>			attachments;
4098 					vector<SubpassDependency>	deps;
4099 
4100 					// Attachments
4101 					for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
4102 					{
4103 						const VkFormat				format						(formats[formatNdx]);
4104 						const VkSampleCountFlagBits	sampleCount					(VK_SAMPLE_COUNT_1_BIT);
4105 						const VkAttachmentLoadOp	loadOp						(VK_ATTACHMENT_LOAD_OP_CLEAR);
4106 						const VkAttachmentStoreOp	storeOp						((attachmentNdx == attachmentCount - 1)
4107 																					? VK_ATTACHMENT_STORE_OP_STORE
4108 																					: VK_ATTACHMENT_STORE_OP_DONT_CARE);
4109 						const VkAttachmentLoadOp	stencilLoadOp				(VK_ATTACHMENT_LOAD_OP_CLEAR);
4110 						const VkAttachmentStoreOp	stencilStoreOp				((attachmentNdx == attachmentCount - 1)
4111 																					? VK_ATTACHMENT_STORE_OP_STORE
4112 																					: VK_ATTACHMENT_STORE_OP_DONT_CARE);
4113 						const VkImageLayout			initialLayout				(VK_IMAGE_LAYOUT_UNDEFINED);
4114 						const VkImageLayout			finalLayout					(VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL);
4115 
4116 						attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalLayout));
4117 					}
4118 
4119 					// Subpasses
4120 					for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
4121 					{
4122 						vector<AttachmentReference>	inputAttachmentReferences;
4123 						const VkImageAspectFlags	inputAttachmentAspectMask	((renderingType == RENDERING_TYPE_RENDERPASS2)
4124 																					? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_DEPTH_BIT)
4125 																					: static_cast<VkImageAspectFlags>(0));
4126 
4127 						// Input attachment references
4128 						if (subpassNdx > 0)
4129 							inputAttachmentReferences.push_back(AttachmentReference((deUint32)subpassNdx - 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, inputAttachmentAspectMask));
4130 
4131 						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>()));
4132 
4133 						// Subpass dependencies from current subpass to previous subpass.
4134 						// Subpasses will wait for the late fragment operations before reading the contents
4135 						// of previous subpass.
4136 						if (subpassNdx > 0)
4137 						{
4138 							deps.push_back(SubpassDependency((deUint32)subpassNdx - 1,							// deUint32				srcPass
4139 															 (deUint32)subpassNdx,								// deUint32				dstPass
4140 															 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,			// VkPipelineStageFlags	srcStageMask
4141 															 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
4142 																| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,	// VkPipelineStageFlags	dstStageMask
4143 															 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags		srcAccessMask
4144 															 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,				// VkAccessFlags		dstAccessMask
4145 															 VK_DEPENDENCY_BY_REGION_BIT));						// VkDependencyFlags	flags
4146 						}
4147 					}
4148 					deps.push_back(SubpassDependency((deUint32)subpassCount - 1,								// deUint32				srcPass
4149 													 VK_SUBPASS_EXTERNAL,										// deUint32				dstPass
4150 													 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,					// VkPipelineStageFlags	srcStageMask
4151 													 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,					// VkPipelineStageFlags	dstStageMask
4152 													 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,				// VkAccessFlags		srcAccessMask
4153 													 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags		dstAccessMask
4154 													 VK_DEPENDENCY_BY_REGION_BIT));								// VkDependencyFlags	flags
4155 
4156 					const RenderPass		renderPass	(attachments, subpasses, deps);
4157 					const SubpassTestConfig	testConfig	(formats[formatNdx], renderSizes[renderSizeNdx], renderPass, renderingType);
4158 					const string			format		(formatToName(formats[formatNdx]).c_str());
4159 
4160 					subpassCountGroup->addChild(new InstanceFactory1<SubpassDependencyTestInstance, SubpassTestConfig, SubpassPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, format, format, testConfig));
4161 				}
4162 
4163 				renderSizeGroup->addChild(subpassCountGroup.release());
4164 			}
4165 
4166 			lateFragmentTestsGroup->addChild(renderSizeGroup.release());
4167 		}
4168 
4169 		group->addChild(lateFragmentTestsGroup.release());
4170 	}
4171 
4172 	// Test subpass self dependency
4173 	{
4174 		const UVec2		renderSizes[]		=
4175 		{
4176 			UVec2(64, 64),
4177 			UVec2(128, 128),
4178 			UVec2(512, 512)
4179 		};
4180 
4181 		de::MovePtr<tcu::TestCaseGroup>	selfDependencyGroup	(new tcu::TestCaseGroup(testCtx, "self_dependency", "self_dependency"));
4182 
4183 		for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
4184 		{
4185 			string groupName	("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" + de::toString(renderSizes[renderSizeNdx].y()));
4186 			de::MovePtr<tcu::TestCaseGroup>	renderSizeGroup	(new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupName.c_str()));
4187 
4188 			const SubpassSelfDependencyBackwardsTestConfig	testConfig	(VK_FORMAT_R8G8B8A8_UNORM, renderSizes[renderSizeNdx], renderingType);
4189 			renderSizeGroup->addChild(new InstanceFactory1<SubpassSelfDependencyBackwardsTestInstance, SubpassSelfDependencyBackwardsTestConfig, SubpassSelfDependencyBackwardsPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "geometry_to_indirectdraw", "", testConfig));
4190 
4191 			selfDependencyGroup->addChild(renderSizeGroup.release());
4192 		}
4193 
4194 		group->addChild(selfDependencyGroup.release());
4195 	}
4196 
4197 	// Test using a single attachment with reads and writes using separate channels. This should work without subpass self-dependency.
4198 	{
4199 		de::MovePtr<tcu::TestCaseGroup>	separateChannelsGroup	(new tcu::TestCaseGroup(testCtx, "separate_channels", "separate_channels"));
4200 
4201 		struct TestConfig
4202 		{
4203 			string		name;
4204 			VkFormat	format;
4205 		} configs[] =
4206 		{
4207 			{	"r8g8b8a8_unorm",		VK_FORMAT_R8G8B8A8_UNORM		},
4208 			{	"r16g16b16a16_sfloat",	VK_FORMAT_R16G16B16A16_SFLOAT	},
4209 			{	"d24_unorm_s8_uint",	VK_FORMAT_D24_UNORM_S8_UINT		},
4210 			{	"d32_sfloat_s8_uint",	VK_FORMAT_D32_SFLOAT_S8_UINT	}
4211 		};
4212 
4213 		for (deUint32 configIdx = 0; configIdx < DE_LENGTH_OF_ARRAY(configs); configIdx++)
4214 		{
4215 			const SeparateChannelsTestConfig testConfig(configs[configIdx].format, renderingType);
4216 
4217 			separateChannelsGroup->addChild(new InstanceFactory1<SeparateChannelsTestInstance, SeparateChannelsTestConfig, SeparateChannelsPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, configs[configIdx].name, "", testConfig));
4218 		}
4219 
4220 		group->addChild(separateChannelsGroup.release());
4221 	}
4222 
4223 	// Test using a single attachment for input and output.
4224 	{
4225 		de::MovePtr<tcu::TestCaseGroup>	singleAttachmentGroup	(new tcu::TestCaseGroup(testCtx, "single_attachment", "single_attachment"));
4226 
4227 		struct TestConfig
4228 		{
4229 			string		name;
4230 			VkFormat	format;
4231 		} configs[] =
4232 		{
4233 			{	"r8g8b8a8_unorm",			VK_FORMAT_R8G8B8A8_UNORM		},
4234 			{	"b8g8r8a8_unorm",			VK_FORMAT_B8G8R8A8_UNORM		},
4235 			{	"r16g16b16a16_sfloat",		VK_FORMAT_R16G16B16A16_SFLOAT	},
4236 			{	"r5g6b5_unorm_pack16",		VK_FORMAT_R5G6B5_UNORM_PACK16	},
4237 			{	"a1r5g5b5_unorm_pack16",	VK_FORMAT_A1R5G5B5_UNORM_PACK16	}
4238 		};
4239 
4240 		for (deUint32 configIdx = 0; configIdx < DE_LENGTH_OF_ARRAY(configs); configIdx++)
4241 		{
4242 			const SingleAttachmentTestConfig testConfig(configs[configIdx].format, renderingType);
4243 
4244 			singleAttachmentGroup->addChild(new InstanceFactory1<SingleAttachmentTestInstance, SingleAttachmentTestConfig, SingleAttachmentPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, configs[configIdx].name, "", testConfig));
4245 		}
4246 
4247 		group->addChild(singleAttachmentGroup.release());
4248 	}
4249 }
4250 } // anonymous
4251 
createRenderPassSubpassDependencyTests(tcu::TestContext & testCtx)4252 tcu::TestCaseGroup* createRenderPassSubpassDependencyTests (tcu::TestContext& testCtx)
4253 {
4254 	return createTestGroup(testCtx, "subpass_dependencies", "Subpass dependency tests", initTests, RENDERING_TYPE_RENDERPASS_LEGACY);
4255 }
4256 
createRenderPass2SubpassDependencyTests(tcu::TestContext & testCtx)4257 tcu::TestCaseGroup* createRenderPass2SubpassDependencyTests (tcu::TestContext& testCtx)
4258 {
4259 	return createTestGroup(testCtx, "subpass_dependencies", "Subpass dependency tests", initTests, RENDERING_TYPE_RENDERPASS2);
4260 }
4261 } // vkt
4262