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 sparse render target.
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 
36 #include "tcuImageCompare.hpp"
37 #include "tcuResultCollector.hpp"
38 #include "tcuTestLog.hpp"
39 #include "tcuTextureUtil.hpp"
40 
41 #include "rrRenderer.hpp"
42 #include "deRandom.hpp"
43 #include "deMath.h"
44 
45 using namespace vk;
46 
47 using tcu::UVec4;
48 using tcu::Vec2;
49 using tcu::UVec2;
50 using tcu::Vec4;
51 
52 using tcu::ConstPixelBufferAccess;
53 using tcu::PixelBufferAccess;
54 
55 using tcu::TestLog;
56 
57 using std::string;
58 using std::vector;
59 using de::SharedPtr;
60 
61 typedef de::SharedPtr<Unique<VkImage> >					SharedPtrVkImage;
62 typedef de::SharedPtr<Unique<VkImageView> >				SharedPtrVkImageView;
63 typedef de::SharedPtr<Unique<VkPipeline> >				SharedPtrVkPipeline;
64 typedef de::SharedPtr<Unique<VkSampler> >				SharedPtrVkSampler;
65 typedef de::SharedPtr<Unique<VkRenderPass> >			SharedPtrVkRenderPass;
66 typedef de::SharedPtr<Unique<VkFramebuffer> >			SharedPtrVkFramebuffer;
67 typedef de::SharedPtr<Unique<VkDescriptorPool> >		SharedPtrVkDescriptorPool;
68 typedef de::SharedPtr<Unique<VkDescriptorSetLayout> >	SharedPtrVkDescriptorLayout;
69 typedef de::SharedPtr<Unique<VkDescriptorSet> >			SharedPtrVkDescriptorSet;
70 typedef de::SharedPtr<Unique<VkPipelineLayout> >		SharedPtrVkPipelineLayout;
71 typedef de::SharedPtr<Unique<VkPipeline> >				SharedPtrVkPipeline;
72 
73 namespace vkt
74 {
75 namespace
76 {
77 using namespace renderpass;
78 
79 template<typename T>
makeSharedPtr(Move<T> move)80 inline SharedPtr<Unique<T> > makeSharedPtr(Move<T> move)
81 {
82 	return SharedPtr<Unique<T> >(new Unique<T>(move));
83 }
84 
85 // Reference renderer shaders
86 class DepthVertShader : public rr::VertexShader
87 {
88 public:
DepthVertShader(void)89 	DepthVertShader (void)
90 	: rr::VertexShader (1, 1)
91 	{
92 		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
93 		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
94 	}
95 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const96 	void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
97 	{
98 		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
99 		{
100 			packets[packetNdx]->position	= rr::readVertexAttribFloat(inputs[0],
101 																		packets[packetNdx]->instanceNdx,
102 																		packets[packetNdx]->vertexNdx);
103 
104 			packets[packetNdx]->outputs[0]	= rr::readVertexAttribFloat(inputs[0],
105 																		packets[packetNdx]->instanceNdx,
106 																		packets[packetNdx]->vertexNdx);
107 		}
108 	}
109 };
110 
111 class DepthFragShader : public rr::FragmentShader
112 {
113 public:
DepthFragShader(void)114 	DepthFragShader (void)
115 	: rr::FragmentShader(1, 1)
116 	{
117 		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
118 		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
119 	}
120 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const121 	void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
122 	{
123 		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
124 		{
125 			rr::FragmentPacket& packet = packets[packetNdx];
126 			for (deUint32 fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
127 			{
128 				const tcu::Vec4 vtxPosition = rr::readVarying<float>(packet, context, 0, fragNdx);
129 
130 				rr::writeFragmentDepth(context, packetNdx, fragNdx, 0, vtxPosition.z());
131 			}
132 		}
133 	}
134 };
135 
createBufferMemory(const DeviceInterface & vk,VkDevice device,Allocator & allocator,VkBuffer buffer)136 de::MovePtr<Allocation> createBufferMemory (const DeviceInterface&	vk,
137 											VkDevice				device,
138 											Allocator&				allocator,
139 											VkBuffer				buffer)
140 {
141 	de::MovePtr<Allocation> allocation (allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), MemoryRequirement::HostVisible));
142 
143 	VK_CHECK(vk.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset()));
144 
145 	return allocation;
146 }
147 
createImageView(const DeviceInterface & vk,VkDevice device,VkImageViewCreateFlags flags,VkImage image,VkImageViewType viewType,VkFormat format,VkComponentMapping components,VkImageSubresourceRange subresourceRange)148 Move<VkImageView> createImageView (const DeviceInterface&	vk,
149 								   VkDevice					device,
150 								   VkImageViewCreateFlags	flags,
151 								   VkImage					image,
152 								   VkImageViewType			viewType,
153 								   VkFormat					format,
154 								   VkComponentMapping		components,
155 								   VkImageSubresourceRange	subresourceRange)
156 {
157 	const VkImageViewCreateInfo pCreateInfo =
158 	{
159 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType
160 		DE_NULL,									// const void*				pNext
161 		flags,										// VkImageViewCreateFlags	flags
162 		image,										// VkImage					image
163 		viewType,									// VkImageViewType			viewType
164 		format,										// VkFormat					format
165 		components,									// VkComponentMapping		components
166 		subresourceRange,							// VkImageSubresourceRange	subresourceRange
167 	};
168 
169 	return createImageView(vk, device, &pCreateInfo);
170 }
171 
createImageViews(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkImage> images,VkFormat format,VkImageAspectFlags aspect)172 vector<SharedPtrVkImageView> createImageViews (const DeviceInterface&	vkd,
173 											   VkDevice					device,
174 											   vector<SharedPtrVkImage>	images,
175 											   VkFormat					format,
176 											   VkImageAspectFlags		aspect)
177 {
178 	vector<SharedPtrVkImageView> imageViews;
179 
180 	for (size_t imageViewNdx = 0; imageViewNdx < images.size(); imageViewNdx++)
181 	{
182 		const VkImageSubresourceRange range =
183 		{
184 			aspect,	// VkImageAspectFlags	aspectMask
185 			0u,		// uint32_t				baseMipLevel
186 			1u,		// uint32_t				levelCount
187 			0u,		// uint32_t				baseArrayLayer
188 			1u		// uint32_t				layerCount
189 		};
190 
191 		imageViews.push_back(makeSharedPtr(createImageView(vkd, device, 0u, **images[imageViewNdx], VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range)));
192 	}
193 
194 	return imageViews;
195 }
196 
createBuffer(const DeviceInterface & vkd,VkDevice device,VkFormat format,deUint32 width,deUint32 height)197 Move<VkBuffer> createBuffer (const DeviceInterface&	vkd,
198 							 VkDevice				device,
199 							 VkFormat				format,
200 							 deUint32				width,
201 							 deUint32				height)
202 {
203 	const VkBufferUsageFlags	bufferUsage	(VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
204 	const VkDeviceSize			pixelSize	= mapVkFormat(format).getPixelSize();
205 	const VkBufferCreateInfo	createInfo	=
206 	{
207 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType
208 		DE_NULL,								// const void*			pNext
209 		0u,										// VkBufferCreateFlags	flags
210 		width * height * pixelSize,				// VkDeviceSize			size
211 		bufferUsage,							// VkBufferUsageFlags	usage
212 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode
213 		0u,										// uint32_t				queueFamilyIndexCount
214 		DE_NULL									// const uint32_t*		pQueueFamilyIndices
215 	};
216 
217 	return createBuffer(vkd, device, &createInfo);
218 }
219 
createDescriptorSetLayouts(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkSampler> & samplers)220 vector<SharedPtrVkDescriptorLayout> createDescriptorSetLayouts (const DeviceInterface&		vkd,
221 																VkDevice					device,
222 																vector<SharedPtrVkSampler>&	samplers)
223 {
224 	vector<SharedPtrVkDescriptorLayout> layouts;
225 
226 	for (size_t layoutNdx = 0; layoutNdx < samplers.size(); layoutNdx++)
227 	{
228 		const VkDescriptorSetLayoutBinding		bindings	=
229 		{
230 				0u,											// uint32_t				binding
231 				VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	// VkDescriptorType		descriptorType
232 				1u,											// uint32_t				descriptorCount
233 				VK_SHADER_STAGE_FRAGMENT_BIT,				// VkShaderStageFlags	stageFlags
234 				&**samplers[layoutNdx]						// const VkSampler*		pImmutableSamplers
235 		};
236 
237 		const VkDescriptorSetLayoutCreateInfo	createInfo	=
238 		{
239 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType						sType
240 			DE_NULL,												// const void*							pNext
241 			0u,														// VkDescriptorSetLayoutCreateFlags		flags
242 			1u,														// uint32_t								bindingCount
243 			&bindings												// const VkDescriptorSetLayoutBinding*	pBindings
244 		};
245 
246 		layouts.push_back(makeSharedPtr(createDescriptorSetLayout(vkd, device, &createInfo)));
247 	}
248 
249 	return layouts;
250 }
251 
createDescriptorPools(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkDescriptorLayout> & layouts,VkDescriptorType type)252 vector<SharedPtrVkDescriptorPool> createDescriptorPools (const DeviceInterface&					vkd,
253 														 VkDevice								device,
254 														 vector<SharedPtrVkDescriptorLayout>&	layouts,
255 														 VkDescriptorType						type)
256 {
257 	vector<SharedPtrVkDescriptorPool> descriptorPools;
258 
259 	for (size_t poolNdx = 0; poolNdx < layouts.size(); poolNdx++)
260 	{
261 		const VkDescriptorPoolSize			size		=
262 		{
263 			type,	// VkDescriptorType		type
264 			1u		// uint32_t				descriptorCount
265 		};
266 
267 		const VkDescriptorPoolCreateInfo	createInfo	=
268 		{
269 			VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,		// VkStructureType				sType
270 			DE_NULL,											// const void*					pNext
271 			VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,	// VkDescriptorPoolCreateFlags	flags
272 			1u,													// uint32_t						maxSets
273 			1u,													// uint32_t						poolSizeCount
274 			&size												// const VkDescriptorPoolSize*	pPoolSizes
275 		};
276 
277 		descriptorPools.push_back(makeSharedPtr(createDescriptorPool(vkd, device, &createInfo)));
278 	}
279 
280 	return descriptorPools;
281 }
282 
283 struct ExternalTestConfig
284 {
ExternalTestConfigvkt::__anon104c10a40111::ExternalTestConfig285 	ExternalTestConfig	(VkFormat			format_,
286 						 UVec2				imageSize_,
287 						 vector<RenderPass>	renderPasses_,
288 						 RenderPassType		renderPassType_,
289 						 deUint32			blurKernel_ = 4)
290 		: format			(format_)
291 		, imageSize			(imageSize_)
292 		, renderPasses		(renderPasses_)
293 		, renderPassType	(renderPassType_)
294 		, blurKernel		(blurKernel_)
295 	{
296 	}
297 
298 	VkFormat			format;
299 	UVec2				imageSize;
300 	vector<RenderPass>	renderPasses;
301 	RenderPassType		renderPassType;
302 	deUint32			blurKernel;
303 };
304 
305 class ExternalDependencyTestInstance : public TestInstance
306 {
307 public:
308 											ExternalDependencyTestInstance	(Context& context, ExternalTestConfig testConfig);
309 											~ExternalDependencyTestInstance	(void);
310 
311 	vector<SharedPtrVkImage>				createAndAllocateImages			(const DeviceInterface&					vk,
312 																			 VkDevice								device,
313 																			 Allocator&								allocator,
314 																			 vector<de::SharedPtr<Allocation> >&	imageMemories,
315 																			 deUint32								universalQueueFamilyIndex,
316 																			 VkFormat								format,
317 																			 deUint32								width,
318 																			 deUint32								height,
319 																			 vector<RenderPass>						renderPasses);
320 
321 	vector<SharedPtrVkSampler>				createSamplers					(const DeviceInterface&					vkd,
322 																			 const VkDevice							device,
323 																			 vector<RenderPass>&					renderPasses);
324 
325 	vector<SharedPtrVkRenderPass>			createRenderPasses				(const DeviceInterface&					vkd,
326 																			 VkDevice								device,
327 																			 vector<RenderPass>						renderPassInfos,
328 																			 const RenderPassType					renderPassType);
329 
330 	 vector<SharedPtrVkFramebuffer>			createFramebuffers				(const DeviceInterface&					vkd,
331 																			 VkDevice								device,
332 																			 vector<SharedPtrVkRenderPass>&			renderPasses,
333 																			 vector<SharedPtrVkImageView>&			dstImageViews,
334 																			 deUint32								width,
335 																			 deUint32								height);
336 
337 	vector<SharedPtrVkPipelineLayout>		createRenderPipelineLayouts		(const DeviceInterface&					vkd,
338 																			 VkDevice								device,
339 																			 vector<SharedPtrVkRenderPass>&			renderPasses,
340 																			 vector<SharedPtrVkDescriptorLayout>&	descriptorSetLayouts);
341 
342 	vector<SharedPtrVkPipeline>				createRenderPipelines			(const DeviceInterface&					vkd,
343 																			 VkDevice								device,
344 																			 vector<SharedPtrVkRenderPass>&			renderPasses,
345 																			 vector<SharedPtrVkPipelineLayout>&		pipelineLayouts,
346 																			 const BinaryCollection&				binaryCollection,
347 																			 deUint32								width,
348 																			 deUint32								height);
349 
350 	vector<SharedPtrVkDescriptorSet>		createDescriptorSets			(const DeviceInterface&					vkd,
351 																			 VkDevice								device,
352 																			 vector<SharedPtrVkDescriptorPool>&		pools,
353 																			 vector<SharedPtrVkDescriptorLayout>&	layouts,
354 																			 vector<SharedPtrVkImageView>&			imageViews,
355 																			 vector<SharedPtrVkSampler>&			samplers);
356 
357 	tcu::TestStatus							iterate							(void);
358 
359 	template<typename RenderpassSubpass>
360 	tcu::TestStatus							iterateInternal					(void);
361 
362 private:
363 	const bool								m_extensionSupported;
364 	const RenderPassType					m_renderPassType;
365 
366 	const deUint32							m_width;
367 	const deUint32							m_height;
368 	const deUint32							m_blurKernel;
369 	const VkFormat							m_format;
370 
371 	vector<de::SharedPtr<Allocation> >		m_imageMemories;
372 	vector<SharedPtrVkImage>				m_images;
373 	vector<SharedPtrVkImageView>			m_imageViews;
374 	vector<SharedPtrVkSampler>				m_samplers;
375 
376 	const Unique<VkBuffer>					m_dstBuffer;
377 	const de::UniquePtr<Allocation>			m_dstBufferMemory;
378 
379 	vector<SharedPtrVkRenderPass>			m_renderPasses;
380 	vector<SharedPtrVkFramebuffer>			m_framebuffers;
381 
382 	vector<SharedPtrVkDescriptorLayout>		m_subpassDescriptorSetLayouts;
383 	vector<SharedPtrVkDescriptorPool>		m_subpassDescriptorPools;
384 	vector<SharedPtrVkDescriptorSet>		m_subpassDescriptorSets;
385 
386 	vector<SharedPtrVkPipelineLayout>		m_renderPipelineLayouts;
387 	vector<SharedPtrVkPipeline>				m_renderPipelines;
388 
389 	const Unique<VkCommandPool>				m_commandPool;
390 	tcu::ResultCollector					m_resultCollector;
391 };
392 
ExternalDependencyTestInstance(Context & context,ExternalTestConfig testConfig)393 ExternalDependencyTestInstance::ExternalDependencyTestInstance (Context& context, ExternalTestConfig testConfig)
394 	: TestInstance					(context)
395 	, m_extensionSupported			((testConfig.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceExtension("VK_KHR_create_renderpass2"))
396 	, m_renderPassType				(testConfig.renderPassType)
397 	, m_width						(testConfig.imageSize.x())
398 	, m_height						(testConfig.imageSize.y())
399 	, m_blurKernel					(testConfig.blurKernel)
400 	, m_format						(testConfig.format)
401 	, m_images						(createAndAllocateImages(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_imageMemories, context.getUniversalQueueFamilyIndex(), m_format, m_width, m_height, testConfig.renderPasses))
402 	, m_imageViews					(createImageViews(context.getDeviceInterface(), context.getDevice(), m_images, m_format, VK_IMAGE_ASPECT_COLOR_BIT))
403 	, m_samplers					(createSamplers(context.getDeviceInterface(), context.getDevice(), testConfig.renderPasses))
404 	, m_dstBuffer					(createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
405 	, m_dstBufferMemory				(createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_dstBuffer))
406 	, m_renderPasses				(createRenderPasses(context.getDeviceInterface(), context.getDevice(), testConfig.renderPasses, testConfig.renderPassType))
407 	, m_framebuffers				(createFramebuffers(context.getDeviceInterface(), context.getDevice(), m_renderPasses, m_imageViews, m_width, m_height))
408 	, m_subpassDescriptorSetLayouts	(createDescriptorSetLayouts(context.getDeviceInterface(), context.getDevice(), m_samplers))
409 	, m_subpassDescriptorPools		(createDescriptorPools(context.getDeviceInterface(), context.getDevice(), m_subpassDescriptorSetLayouts, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER))
410 	, m_subpassDescriptorSets		(createDescriptorSets(context.getDeviceInterface(), context.getDevice(), m_subpassDescriptorPools, m_subpassDescriptorSetLayouts, m_imageViews, m_samplers))
411 	, m_renderPipelineLayouts		(createRenderPipelineLayouts(context.getDeviceInterface(), context.getDevice(), m_renderPasses, m_subpassDescriptorSetLayouts))
412 	, m_renderPipelines				(createRenderPipelines(context.getDeviceInterface(), context.getDevice(), m_renderPasses, m_renderPipelineLayouts, context.getBinaryCollection(), m_width, m_height))
413 	, m_commandPool					(createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
414 {
415 }
416 
~ExternalDependencyTestInstance(void)417 ExternalDependencyTestInstance::~ExternalDependencyTestInstance (void)
418 {
419 }
420 
createAndAllocateImages(const DeviceInterface & vk,VkDevice device,Allocator & allocator,vector<de::SharedPtr<Allocation>> & imageMemories,deUint32 universalQueueFamilyIndex,VkFormat format,deUint32 width,deUint32 height,vector<RenderPass> renderPasses)421 vector<SharedPtrVkImage> ExternalDependencyTestInstance::createAndAllocateImages (const DeviceInterface&				vk,
422 																				  VkDevice								device,
423 																				  Allocator&							allocator,
424 																				  vector<de::SharedPtr<Allocation> >&	imageMemories,
425 																				  deUint32								universalQueueFamilyIndex,
426 																				  VkFormat								format,
427 																				  deUint32								width,
428 																				  deUint32								height,
429 																				  vector<RenderPass>					renderPasses)
430 {
431 	vector<SharedPtrVkImage> images;
432 
433 	for (size_t imageNdx = 0; imageNdx < renderPasses.size(); imageNdx++)
434 	{
435 		const VkExtent3D		imageExtent		=
436 		{
437 			width,		// uint32_t		width
438 			height,		// uint32_t		height
439 			1u			// uint32_t		depth
440 		};
441 
442 		const VkImageCreateInfo	imageCreateInfo	=
443 		{
444 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
445 			DE_NULL,								// const void*				pNext
446 			0u,										// VkImageCreateFlags		flags
447 			VK_IMAGE_TYPE_2D,						// VkImageType				imageType
448 			format,									// VkFormat					format
449 			imageExtent,							// VkExtent3D				extent
450 			1u,										// uint32_t					mipLevels
451 			1u,										// uint32_t					arrayLayers
452 			VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
453 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
454 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
455 				| VK_IMAGE_USAGE_SAMPLED_BIT
456 				| VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage
457 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
458 			1u,										// uint32_t					queueFamilyIndexCount
459 			&universalQueueFamilyIndex,				// const uint32_t*			pQueueFamilyIndices
460 			VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
461 		};
462 
463 		images.push_back(makeSharedPtr(vk::createImage(vk, device, &imageCreateInfo, DE_NULL)));
464 		imageMemories.push_back((de::SharedPtr<Allocation>)allocator.allocate(getImageMemoryRequirements(vk, device, **images[imageNdx]), MemoryRequirement::Any).release());
465 		VK_CHECK(vk.bindImageMemory(device, **images[imageNdx], imageMemories[imageNdx]->getMemory(), imageMemories[imageNdx]->getOffset()));
466 	}
467 
468 	return images;
469 }
470 
createSamplers(const DeviceInterface & vkd,const VkDevice device,vector<RenderPass> & renderPasses)471 vector<SharedPtrVkSampler> ExternalDependencyTestInstance::createSamplers (const DeviceInterface&	vkd,
472 																		   const VkDevice			device,
473 																		   vector<RenderPass>&		renderPasses)
474 {
475 	vector<SharedPtrVkSampler> samplers;
476 
477 	for (size_t samplerNdx = 0; samplerNdx < renderPasses.size() - 1; samplerNdx++)
478 	{
479 		const VkSamplerCreateInfo samplerInfo =
480 		{
481 			VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,		// VkStructureType			sType
482 			DE_NULL,									// const void*				pNext
483 			0u,											// VkSamplerCreateFlags		flags
484 			VK_FILTER_NEAREST,							// VkFilter					magFilter
485 			VK_FILTER_NEAREST,							// VkFilter					minFilter
486 			VK_SAMPLER_MIPMAP_MODE_NEAREST,				// VkSamplerMipmapMode		mipmapMode
487 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeU
488 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeV
489 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeW
490 			0.0f,										// float					mipLodBias
491 			VK_FALSE,									// VkBool32					anisotropyEnable
492 			1.0f,										// float					maxAnisotropy
493 			VK_FALSE,									// VkBool32					compareEnable
494 			VK_COMPARE_OP_ALWAYS,						// VkCompareOp				compareOp
495 			0.0f,										// float					minLod
496 			0.0f,										// float					maxLod
497 			VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,	// VkBorderColor			borderColor
498 			VK_FALSE,									// VkBool32					unnormalizedCoordinates
499 		};
500 
501 		samplers.push_back(makeSharedPtr(createSampler(vkd, device, &samplerInfo)));
502 	}
503 
504 	return samplers;
505 }
506 
createRenderPasses(const DeviceInterface & vkd,VkDevice device,vector<RenderPass> renderPassInfos,const RenderPassType renderPassType)507 vector<SharedPtrVkRenderPass> ExternalDependencyTestInstance::createRenderPasses (const DeviceInterface&	vkd,
508 																				  VkDevice					device,
509 																				  vector<RenderPass>		renderPassInfos,
510 																				  const RenderPassType		renderPassType)
511 {
512 	vector<SharedPtrVkRenderPass> renderPasses;
513 
514 	for (size_t renderPassNdx = 0; renderPassNdx < renderPassInfos.size(); renderPassNdx++)
515 	{
516 		renderPasses.push_back(makeSharedPtr(createRenderPass(vkd, device, renderPassInfos[renderPassNdx], renderPassType)));
517 	}
518 
519 	return renderPasses;
520 }
521 
createFramebuffers(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkRenderPass> & renderPasses,vector<SharedPtrVkImageView> & dstImageViews,deUint32 width,deUint32 height)522 vector<SharedPtrVkFramebuffer> ExternalDependencyTestInstance::createFramebuffers (const DeviceInterface&			vkd,
523 																				   VkDevice							device,
524 																				   vector<SharedPtrVkRenderPass>&	renderPasses,
525 																				   vector<SharedPtrVkImageView>&	dstImageViews,
526 																				   deUint32							width,
527 																				   deUint32							height)
528 {
529 	vector<SharedPtrVkFramebuffer> framebuffers;
530 
531 	for (size_t renderPassNdx = 0; renderPassNdx < renderPasses.size(); renderPassNdx++)
532 	{
533 		VkRenderPass renderPass (**renderPasses[renderPassNdx]);
534 
535 		const VkFramebufferCreateInfo createInfo =
536 		{
537 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType
538 			DE_NULL,									// const void*				pNext
539 			0u,											// VkFramebufferCreateFlags	flags
540 			renderPass,									// VkRenderPass				renderPass
541 			1u,											// uint32_t					attachmentCount
542 			&**dstImageViews[renderPassNdx],			// const VkImageView*		pAttachments
543 			width,										// uint32_t					width
544 			height,										// uint32_t					height
545 			1u											// uint32_t					layers
546 		};
547 
548 		framebuffers.push_back(makeSharedPtr(createFramebuffer(vkd, device, &createInfo)));
549 	}
550 
551 	return framebuffers;
552 }
553 
createDescriptorSets(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkDescriptorPool> & pools,vector<SharedPtrVkDescriptorLayout> & layouts,vector<SharedPtrVkImageView> & imageViews,vector<SharedPtrVkSampler> & samplers)554 vector<SharedPtrVkDescriptorSet> ExternalDependencyTestInstance::createDescriptorSets (const DeviceInterface&				vkd,
555 																					   VkDevice								device,
556 																					   vector<SharedPtrVkDescriptorPool>&	pools,
557 																					   vector<SharedPtrVkDescriptorLayout>&	layouts,
558 																					   vector<SharedPtrVkImageView>&		imageViews,
559 																					   vector<SharedPtrVkSampler>&			samplers)
560 {
561 	vector<SharedPtrVkDescriptorSet> descriptorSets;
562 
563 	for (size_t setNdx = 0; setNdx < layouts.size(); setNdx++)
564 	{
565 		const VkDescriptorSetAllocateInfo allocateInfo =
566 		{
567 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,	// VkStructureType					sType
568 			DE_NULL,										// const void*						pNext
569 			**pools[setNdx],								// VkDescriptorPool					descriptorPool
570 			1u,												// uint32_t							descriptorSetCount
571 			&**layouts[setNdx]								// const VkDescriptorSetLayout*		pSetLayouts
572 		};
573 
574 		descriptorSets.push_back(makeSharedPtr(allocateDescriptorSet(vkd, device, &allocateInfo)));
575 
576 		{
577 			const VkDescriptorImageInfo	imageInfo	=
578 			{
579 				**samplers[setNdx],							// VkSampler		sampler
580 				**imageViews[setNdx],						// VkImageView		imageView
581 				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL	// VkImageLayout	imageLayout
582 			};
583 
584 			const VkWriteDescriptorSet	write		=
585 			{
586 				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,		// VkStructureType					sType
587 				DE_NULL,									// const void*						pNext
588 				**descriptorSets[setNdx],					// VkDescriptorSet					dstSet
589 				0u,											// uint32_t							dstBinding
590 				0u,											// uint32_t							dstArrayElement
591 				1u,											// uint32_t							descriptorCount
592 				VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	// VkDescriptorType					descriptorType
593 				&imageInfo,									// const VkDescriptorImageInfo*		pImageInfo
594 				DE_NULL,									// const VkDescriptorBufferInfo*	pBufferInfo
595 				DE_NULL										// const VkBufferView*				pTexelBufferView
596 			};
597 
598 			vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
599 		}
600 	}
601 
602 	return descriptorSets;
603 }
604 
createRenderPipelineLayouts(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkRenderPass> & renderPasses,vector<SharedPtrVkDescriptorLayout> & descriptorSetLayouts)605 vector<SharedPtrVkPipelineLayout> ExternalDependencyTestInstance::createRenderPipelineLayouts (const DeviceInterface&				vkd,
606 																							   VkDevice								device,
607 																							   vector<SharedPtrVkRenderPass>&		renderPasses,
608 																							   vector<SharedPtrVkDescriptorLayout>&	descriptorSetLayouts)
609 {
610 	vector<SharedPtrVkPipelineLayout> pipelineLayouts;
611 
612 	for (size_t renderPassNdx = 0; renderPassNdx < renderPasses.size(); renderPassNdx++)
613 	{
614 		const VkPipelineLayoutCreateInfo createInfo =
615 		{
616 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,								// VkStructureType				sType
617 			DE_NULL,																	// const void*					pNext
618 			(vk::VkPipelineLayoutCreateFlags)0,											// VkPipelineLayoutCreateFlags	flags
619 			renderPassNdx > 0 ? 1u : 0u,												// deUint32						setLayoutCount
620 			renderPassNdx > 0 ? &**descriptorSetLayouts[renderPassNdx - 1] : DE_NULL,	// const VkDescriptorSetLayout*	pSetLayouts
621 			0u,																			// deUint32						pushConstantRangeCount
622 			DE_NULL																		// const VkPushConstantRange*	pPushConstantRanges
623 		};
624 
625 		pipelineLayouts.push_back(makeSharedPtr(createPipelineLayout(vkd, device, &createInfo)));
626 	}
627 
628 	return pipelineLayouts;
629 }
630 
createRenderPipelines(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkRenderPass> & renderPasses,vector<SharedPtrVkPipelineLayout> & pipelineLayouts,const BinaryCollection & binaryCollection,deUint32 width,deUint32 height)631 vector<SharedPtrVkPipeline> ExternalDependencyTestInstance::createRenderPipelines (const DeviceInterface&				vkd,
632 																				   VkDevice								device,
633 																				   vector<SharedPtrVkRenderPass>&		renderPasses,
634 																				   vector<SharedPtrVkPipelineLayout>&	pipelineLayouts,
635 																				   const BinaryCollection&				binaryCollection,
636 																				   deUint32								width,
637 																				   deUint32								height)
638 {
639 	vector<SharedPtrVkPipeline> pipelines;
640 
641 	for (size_t renderPassNdx = 0; renderPassNdx < renderPasses.size(); renderPassNdx++)
642 	{
643 		const Unique<VkShaderModule>					vertexShaderModule		(createShaderModule(vkd, device, binaryCollection.get("quad-vert-" + de::toString(renderPassNdx)), 0u));
644 		const Unique<VkShaderModule>					fragmentShaderModule	(createShaderModule(vkd, device, binaryCollection.get("quad-frag-" + de::toString(renderPassNdx)), 0u));
645 
646 		const VkPipelineVertexInputStateCreateInfo		vertexInputState		=
647 		{
648 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType
649 			DE_NULL,													// const void*								pNext
650 			(VkPipelineVertexInputStateCreateFlags)0u,					// VkPipelineVertexInputStateCreateFlags	flags
651 			0u,															// uint32_t									vertexBindingDescriptionCount
652 			DE_NULL,													// const VkVertexInputBindingDescription*	pVertexBindingDescriptions
653 			0u,															// uint32_t									vertexAttributeDescriptionCount
654 			DE_NULL														// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions
655 		};
656 
657 		const std::vector<VkViewport>					viewports				(1, makeViewport(tcu::UVec2(width, height)));
658 		const std::vector<VkRect2D>						scissors				(1, makeRect2D(tcu::UVec2(width, height)));
659 		const VkRenderPass								renderPass				(**renderPasses[renderPassNdx]);
660 		const VkPipelineLayout							layout					(**pipelineLayouts[renderPassNdx]);
661 
662 		pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(vkd,									// const DeviceInterface&						vk
663 															   device,								// const VkDevice								device
664 															   layout,								// const VkPipelineLayout						pipelineLayout
665 															   *vertexShaderModule,					// const VkShaderModule							vertexShaderModule
666 															   DE_NULL,								// const VkShaderModule							tessellationControlShaderModule
667 															   DE_NULL,								// const VkShaderModule							tessellationEvalShaderModule
668 															   DE_NULL,								// const VkShaderModule							geometryShaderModule
669 															   *fragmentShaderModule,				// const VkShaderModule							fragmentShaderModule
670 															   renderPass,							// const VkRenderPass							renderPass
671 															   viewports,							// const std::vector<VkViewport>&				viewports
672 															   scissors,							// const std::vector<VkRect2D>&					scissors
673 															   VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology					topology
674 															   0u,									// const deUint32								subpass
675 															   0u,									// const deUint32								patchControlPoints
676 															   &vertexInputState)));				// const VkPipelineVertexInputStateCreateInfo*	vertexInputStateCreateInfo
677 	}
678 
679 	return pipelines;
680 }
681 
iterate(void)682 tcu::TestStatus ExternalDependencyTestInstance::iterate (void)
683 {
684 	switch (m_renderPassType)
685 	{
686 		case RENDERPASS_TYPE_LEGACY:
687 			return iterateInternal<RenderpassSubpass1>();
688 		case RENDERPASS_TYPE_RENDERPASS2:
689 			return iterateInternal<RenderpassSubpass2>();
690 		default:
691 			TCU_THROW(InternalError, "Impossible");
692 	}
693 }
694 
695 template<typename RenderpassSubpass>
iterateInternal(void)696 tcu::TestStatus ExternalDependencyTestInstance::iterateInternal (void)
697 {
698 	const DeviceInterface&								vkd					(m_context.getDeviceInterface());
699 	const Unique<VkCommandBuffer>						commandBuffer		(allocateCommandBuffer(vkd, m_context.getDevice(), *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
700 	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo	(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
701 	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo		(DE_NULL);
702 
703 	beginCommandBuffer(vkd, *commandBuffer);
704 
705 	for (size_t renderPassNdx = 0; renderPassNdx < m_renderPasses.size(); renderPassNdx++)
706 	{
707 		// Begin render pass
708 		{
709 			VkRect2D renderArea =
710 			{
711 				{ 0u, 0u },				// VkOffset2D	offset
712 				{ m_width, m_height }	// VkExtent2D	extent
713 			};
714 
715 			const VkRenderPassBeginInfo beginInfo =
716 			{
717 				VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType
718 				DE_NULL,									// const void*			pNext
719 				**m_renderPasses[renderPassNdx],			// VkRenderPass			renderPass
720 				**m_framebuffers[renderPassNdx],			// VkFramebuffer		framebuffer
721 				renderArea,									// VkRect2D				renderArea
722 				0u,											// uint32_t				clearValueCount
723 				DE_NULL										// const VkClearValue*	pClearValues
724 			};
725 
726 			RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
727 		}
728 
729 		vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_renderPipelines[renderPassNdx]);
730 
731 		// Use results from the previous pass as input texture
732 		if (renderPassNdx > 0)
733 			vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_renderPipelineLayouts[renderPassNdx], 0, 1, &**m_subpassDescriptorSets[renderPassNdx - 1], 0, DE_NULL);
734 
735 		vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
736 
737 		RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
738 	}
739 
740 	// Memory barrier between rendering and copy
741 	{
742 		VkImageSubresourceRange		imageSubresourceRange	=
743 		{
744 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask
745 			0u,							// uint32_t				baseMipLevel
746 			1u,							// uint32_t				levelCount
747 			0u,							// uint32_t				baseArrayLayer
748 			1u							// uint32_t				layerCount
749 		};
750 
751 		const VkImageMemoryBarrier	barrier					=
752 		{
753 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType
754 			DE_NULL,									// const void*				pNext
755 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask
756 			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask
757 			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,	// VkImageLayout			oldLayout
758 			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout
759 			VK_QUEUE_FAMILY_IGNORED,					// uint32_t					srcQueueFamilyIndex
760 			VK_QUEUE_FAMILY_IGNORED,					// uint32_t					dstQueueFamilyIndex
761 			**m_images[m_renderPasses.size() - 1],		// VkImage					image
762 			imageSubresourceRange						// VkImageSubresourceRange	subresourceRange
763 		};
764 
765 		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
766 	}
767 
768 	// Copy image memory to buffer
769 	{
770 		const VkImageSubresourceLayers imageSubresourceLayers =
771 		{
772 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask
773 			0u,							// deUint32				mipLevel
774 			0u,							// deUint32				baseArrayLayer
775 			1u							// deUint32				layerCount
776 		};
777 
778 		const VkBufferImageCopy region =
779 		{
780 			0u,							// VkDeviceSize				bufferOffset
781 			0u,							// uint32_t					bufferRowLength
782 			0u,							// uint32_t					bufferImageHeight
783 			imageSubresourceLayers,		// VkImageSubresourceLayers	imageSubresource
784 			{ 0u, 0u, 0u },				// VkOffset3D				imageOffset
785 			{ m_width, m_height, 1u }	// VkExtent3D				imageExtent
786 		};
787 
788 		vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[m_renderPasses.size() - 1], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_dstBuffer, 1u, &region);
789 	}
790 
791 	// Memory barrier between copy and host access
792 	{
793 		const VkBufferMemoryBarrier barrier =
794 		{
795 			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType
796 			DE_NULL,									// const void*		pNext
797 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask
798 			VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask
799 			VK_QUEUE_FAMILY_IGNORED,					// uint32_t			srcQueueFamilyIndex
800 			VK_QUEUE_FAMILY_IGNORED,					// uint32_t			dstQueueFamilyIndex
801 			*m_dstBuffer,								// VkBuffer			buffer
802 			0u,											// VkDeviceSize		offset
803 			VK_WHOLE_SIZE								// VkDeviceSize		size
804 		};
805 
806 		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
807 	}
808 
809 	endCommandBuffer(vkd, *commandBuffer);
810 	submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
811 	invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_dstBufferMemory->getMemory(), m_dstBufferMemory->getOffset(), VK_WHOLE_SIZE);
812 
813 	{
814 		const tcu::TextureFormat			format		(mapVkFormat(m_format));
815 		const void* const					ptr			(m_dstBufferMemory->getHostPtr());
816 		const tcu::ConstPixelBufferAccess	access		(format, m_width, m_height, 1, ptr);
817 		tcu::TextureLevel					reference	(format, m_width, m_height);
818 		tcu::TextureLevel					textureA	(format, m_width, m_height);
819 		tcu::TextureLevel					textureB	(format, m_width, m_height);
820 
821 		for (deUint32 renderPassNdx = 0; renderPassNdx < m_renderPasses.size(); renderPassNdx++)
822 		{
823 			// First pass renders four quads of different color, which will be blurred in the following passes
824 			if (renderPassNdx == 0)
825 			{
826 				for (deUint32 y = 0; y < m_height; y++)
827 				for (deUint32 x = 0; x < m_width; x++)
828 				{
829 					if (x <= (m_width - 1) / 2 && y <= (m_height - 1) / 2)
830 						textureA.getAccess().setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
831 					else if (x > (m_width - 1) / 2 && y <= (m_height - 1) / 2)
832 						textureA.getAccess().setPixel(Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
833 					else if (x <= (m_width - 1) / 2 && y > (m_height - 1) / 2)
834 						textureA.getAccess().setPixel(Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
835 					else
836 						textureA.getAccess().setPixel(Vec4(0.0f, 0.0f, 0.0f, 1.0f), x, y);
837 				}
838 			}
839 			// Blur previous pass
840 			else
841 			{
842 				for (deUint32 y = 0; y < m_height; y++)
843 				for (deUint32 x = 0; x < m_width; x++)
844 				{
845 					Vec4 blurColor (Vec4(0.0));
846 
847 					for (deUint32 sampleNdx = 0; sampleNdx < (m_blurKernel + 1); sampleNdx++)
848 					{
849 						if (renderPassNdx % 2 == 0)
850 						{
851 							// Do a horizontal blur
852 							blurColor += 0.12f * textureB.getAccess().getPixel(deClamp32((deInt32)x - (m_blurKernel / 2) + sampleNdx, 0u, m_width - 1u), y);
853 						}
854 						else
855 						{
856 							// Do a vertical blur
857 							blurColor += 0.12f * textureA.getAccess().getPixel(x, deClamp32((deInt32)y - (m_blurKernel / 2) + sampleNdx, 0u, m_height - 1u));
858 						}
859 					}
860 
861 					renderPassNdx % 2 == 0 ? textureA.getAccess().setPixel(blurColor, x, y) : textureB.getAccess().setPixel(blurColor, x, y);
862 				}
863 			}
864 		}
865 
866 		reference = m_renderPasses.size() % 2 == 0 ? textureB : textureA;
867 
868 		{
869 			// Allow error of 4 times the minimum presentable difference
870 			const Vec4 threshold (4.0f * 1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>()) - 1u).cast<float>());
871 
872 			if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
873 				m_resultCollector.fail("Compare failed.");
874 		}
875 	}
876 
877 	return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
878 }
879 
880 struct SubpassTestConfig
881 {
SubpassTestConfigvkt::__anon104c10a40111::SubpassTestConfig882 		SubpassTestConfig	(VkFormat		format_,
883 							 UVec2			imageSize_,
884 							 RenderPass		renderPass_,
885 							 RenderPassType	renderPassType_)
886 		: format			(format_)
887 		, imageSize			(imageSize_)
888 		, renderPass		(renderPass_)
889 		, renderPassType	(renderPassType_)
890 	{
891 	}
892 
893 	VkFormat			format;
894 	UVec2				imageSize;
895 	RenderPass			renderPass;
896 	RenderPassType		renderPassType;
897 };
898 
899 class SubpassDependencyTestInstance : public TestInstance
900 {
901 public:
902 										SubpassDependencyTestInstance	(Context&								context,
903 																		 SubpassTestConfig						testConfig);
904 
905 										~SubpassDependencyTestInstance	(void);
906 
907 	vector<SharedPtrVkImage>			createAndAllocateImages			(const DeviceInterface&					vk,
908 																		 VkDevice								device,
909 																		 Allocator&								allocator,
910 																		 vector<de::SharedPtr<Allocation> >&	imageMemories,
911 																		 deUint32								universalQueueFamilyIndex,
912 																		 RenderPass								renderPassInfo,
913 																		 VkFormat								format,
914 																		 deUint32								width,
915 																		 deUint32								height);
916 
917 	vector<SharedPtrVkPipelineLayout>	createRenderPipelineLayouts		(const DeviceInterface&					vkd,
918 																		 VkDevice								device,
919 																		 RenderPass								renderPassInfo,
920 																		 vector<SharedPtrVkDescriptorLayout>	descriptorSetLayouts);
921 
922 	vector<SharedPtrVkPipeline>			createRenderPipelines			(const DeviceInterface&					vkd,
923 																		 VkDevice								device,
924 																		 RenderPass								renderPassInfo,
925 																		 VkRenderPass							renderPass,
926 																		 vector<SharedPtrVkPipelineLayout>&		pipelineLayouts,
927 																		 const BinaryCollection&				binaryCollection,
928 																		 VkFormat								format,
929 																		 deUint32								width,
930 																		 deUint32								height);
931 
932 	Move<VkFramebuffer>					createFramebuffer				(const DeviceInterface&					vkd,
933 																		 VkDevice								device,
934 																		 RenderPass								renderPassInfo,
935 																		 VkRenderPass							renderPass,
936 																		 vector<SharedPtrVkImageView>&			dstImageViews,
937 																		 deUint32								width,
938 																		 deUint32								height);
939 
940 	vector<SharedPtrVkDescriptorLayout>	createDescriptorSetLayouts		(const DeviceInterface&					vkd,
941 																		 VkDevice								device,
942 																		 RenderPass								renderPassInfo);
943 
944 	vector<SharedPtrVkDescriptorSet>	createDescriptorSets			(const DeviceInterface&					vkd,
945 																		 VkDevice								device,
946 																		 VkFormat								format,
947 																		 vector<SharedPtrVkDescriptorPool>&		pools,
948 																		 vector<SharedPtrVkDescriptorLayout>&	layouts,
949 																		 vector<SharedPtrVkImageView>&			imageViews);
950 
951 	tcu::TextureLevel					getRepresentableDepthChannel	(const ConstPixelBufferAccess&			access);
952 
953 	bool								verifyDepth						(const ConstPixelBufferAccess&			reference,
954 																		 const ConstPixelBufferAccess&			result,
955 																		 const float							threshold);
956 
957 	bool								verifyStencil					(const ConstPixelBufferAccess&			reference,
958 																		 const ConstPixelBufferAccess&			result);
959 
960 	tcu::TestStatus						iterate							(void);
961 
962 	template<typename RenderpassSubpass>
963 	tcu::TestStatus						iterateInternal					(void);
964 
965 private:
966 	const bool							m_extensionSupported;
967 	const RenderPass					m_renderPassInfo;
968 	const RenderPassType				m_renderPassType;
969 
970 	const deUint32						m_width;
971 	const deUint32						m_height;
972 	const VkFormat						m_format;
973 
974 	vector<de::SharedPtr<Allocation> >	m_imageMemories;
975 	vector<SharedPtrVkImage>			m_images;
976 	vector<SharedPtrVkImageView>		m_imageViews;
977 
978 	const Unique<VkBuffer>				m_primaryBuffer;
979 	const Unique<VkBuffer>				m_secondaryBuffer;
980 	const de::UniquePtr<Allocation>		m_primaryBufferMemory;
981 	const de::UniquePtr<Allocation>		m_secondaryBufferMemory;
982 
983 	const Unique<VkRenderPass>			m_renderPass;
984 	const Unique<VkFramebuffer>			m_framebuffer;
985 
986 	vector<SharedPtrVkDescriptorLayout>	m_subpassDescriptorSetLayouts;
987 	vector<SharedPtrVkDescriptorPool>	m_subpassDescriptorPools;
988 	vector<SharedPtrVkDescriptorSet>	m_subpassDescriptorSets;
989 
990 	vector<SharedPtrVkPipelineLayout>	m_renderPipelineLayouts;
991 	vector<SharedPtrVkPipeline>			m_renderPipelines;
992 
993 	const Unique<VkCommandPool>			m_commandPool;
994 	tcu::ResultCollector				m_resultCollector;
995 };
996 
SubpassDependencyTestInstance(Context & context,SubpassTestConfig testConfig)997 SubpassDependencyTestInstance::SubpassDependencyTestInstance (Context& context, SubpassTestConfig testConfig)
998 	: TestInstance					(context)
999 	, m_extensionSupported			((testConfig.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceExtension("VK_KHR_create_renderpass2"))
1000 	, m_renderPassInfo				(testConfig.renderPass)
1001 	, m_renderPassType				(testConfig.renderPassType)
1002 	, m_width						(testConfig.imageSize.x())
1003 	, m_height						(testConfig.imageSize.y())
1004 	, m_format						(testConfig.format)
1005 	, m_images						(createAndAllocateImages(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_imageMemories, context.getUniversalQueueFamilyIndex(), m_renderPassInfo, m_format, m_width, m_height))
1006 	, m_imageViews					(createImageViews(context.getDeviceInterface(), context.getDevice(), m_images, m_format, isDepthStencilFormat(m_format) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT))
1007 	, m_primaryBuffer				(createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
1008 	, m_secondaryBuffer				(createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
1009 	, m_primaryBufferMemory			(createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_primaryBuffer))
1010 	, m_secondaryBufferMemory		(createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_secondaryBuffer))
1011 	, m_renderPass					(createRenderPass(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo, testConfig.renderPassType))
1012 	, m_framebuffer					(createFramebuffer(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo, *m_renderPass, m_imageViews, m_width, m_height))
1013 	, m_subpassDescriptorSetLayouts	(createDescriptorSetLayouts(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo))
1014 	, m_subpassDescriptorPools		(createDescriptorPools(context.getDeviceInterface(), context.getDevice(), m_subpassDescriptorSetLayouts, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT))
1015 	, m_subpassDescriptorSets		(createDescriptorSets(context.getDeviceInterface(), context.getDevice(), m_format, m_subpassDescriptorPools, m_subpassDescriptorSetLayouts, m_imageViews))
1016 	, m_renderPipelineLayouts		(createRenderPipelineLayouts(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo, m_subpassDescriptorSetLayouts))
1017 	, m_renderPipelines				(createRenderPipelines(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo, *m_renderPass, m_renderPipelineLayouts, context.getBinaryCollection(), m_format, m_width, m_height))
1018 	, m_commandPool					(createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
1019 {
1020 }
1021 
~SubpassDependencyTestInstance(void)1022 SubpassDependencyTestInstance::~SubpassDependencyTestInstance (void)
1023 {
1024 }
1025 
createAndAllocateImages(const DeviceInterface & vk,VkDevice device,Allocator & allocator,vector<de::SharedPtr<Allocation>> & imageMemories,deUint32 universalQueueFamilyIndex,RenderPass renderPassInfo,VkFormat format,deUint32 width,deUint32 height)1026 vector<SharedPtrVkImage> SubpassDependencyTestInstance::createAndAllocateImages (const DeviceInterface&					vk,
1027 																				 VkDevice								device,
1028 																				 Allocator&								allocator,
1029 																				 vector<de::SharedPtr<Allocation> >&	imageMemories,
1030 																				 deUint32								universalQueueFamilyIndex,
1031 																				 RenderPass								renderPassInfo,
1032 																				 VkFormat								format,
1033 																				 deUint32								width,
1034 																				 deUint32								height)
1035 {
1036 	// Verify format support
1037 	{
1038 		const VkFormatFeatureFlags	flags		= isDepthStencilFormat(m_format) ? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
1039 		const VkFormatProperties	properties	= vk::getPhysicalDeviceFormatProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format);
1040 
1041 		if ((properties.optimalTilingFeatures & flags) != flags)
1042 			TCU_THROW(NotSupportedError, "Format not supported");
1043 	}
1044 
1045 	vector<SharedPtrVkImage> images;
1046 
1047 	for (size_t imageNdx = 0; imageNdx < renderPassInfo.getAttachments().size(); imageNdx++)
1048 	{
1049 		const VkExtent3D		imageExtent		=
1050 		{
1051 			width,		// uint32_t	width
1052 			height,		// uint32_t	height
1053 			1u			// uint32_t	depth
1054 		};
1055 
1056 		VkImageUsageFlags		usage			= ((isDepthStencilFormat(format)
1057 													? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
1058 													: VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
1059 													| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
1060 													| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
1061 
1062 		const VkImageCreateInfo	imageCreateInfo	=
1063 		{
1064 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
1065 			DE_NULL,								// const void*				pNext
1066 			0u,										// VkImageCreateFlags		flags
1067 			VK_IMAGE_TYPE_2D,						// VkImageType				imageType
1068 			format,									// VkFormat					format
1069 			imageExtent,							// VkExtent3D				extent
1070 			1u,										// uint32_t					mipLevels
1071 			1u,										// uint32_t					arrayLayers
1072 			VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
1073 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
1074 			usage,									// VkImageUsageFlags		usage
1075 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
1076 			1u,										// uint32_t					queueFamilyIndexCount
1077 			&universalQueueFamilyIndex,				// const uint32_t*			pQueueFamilyIndices
1078 			VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
1079 		};
1080 
1081 		images.push_back(makeSharedPtr(vk::createImage(vk, device, &imageCreateInfo, DE_NULL)));
1082 		imageMemories.push_back((de::SharedPtr<Allocation>)allocator.allocate(getImageMemoryRequirements(vk, device, **images[imageNdx]), MemoryRequirement::Any).release());
1083 		VK_CHECK(vk.bindImageMemory(device, **images[imageNdx], imageMemories[imageNdx]->getMemory(), imageMemories[imageNdx]->getOffset()));
1084 	}
1085 
1086 	return images;
1087 }
1088 
createRenderPipelineLayouts(const DeviceInterface & vkd,VkDevice device,RenderPass renderPassInfo,vector<SharedPtrVkDescriptorLayout> descriptorSetLayouts)1089 vector<SharedPtrVkPipelineLayout> SubpassDependencyTestInstance::createRenderPipelineLayouts (const DeviceInterface&				vkd,
1090 																							  VkDevice								device,
1091 																							  RenderPass							renderPassInfo,
1092 																							  vector<SharedPtrVkDescriptorLayout>	descriptorSetLayouts)
1093 {
1094 	vector<SharedPtrVkPipelineLayout>	pipelineLayouts;
1095 	vector<VkDescriptorSetLayout>		descriptorSetLayoutHandles;
1096 	const size_t						descriptorSetLayoutCount	= descriptorSetLayouts.size();
1097 
1098 	for (size_t descriptorSetLayoutNdx = 0; descriptorSetLayoutNdx < descriptorSetLayoutCount; descriptorSetLayoutNdx++)
1099 		descriptorSetLayoutHandles.push_back(**descriptorSetLayouts.at(descriptorSetLayoutNdx));
1100 
1101 	for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
1102 	{
1103 		const VkPipelineLayoutCreateInfo createInfo =
1104 		{
1105 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType
1106 			DE_NULL,										// const void*					pNext
1107 			(vk::VkPipelineLayoutCreateFlags)0,				// VkPipelineLayoutCreateFlags	flags
1108 			(deUint32)descriptorSetLayoutCount,				// deUint32						setLayoutCount
1109 			descriptorSetLayoutHandles.data(),				// const VkDescriptorSetLayout*	pSetLayouts
1110 			0u,												// deUint32						pushConstantRangeCount
1111 			DE_NULL											// const VkPushConstantRange*	pPushConstantRanges
1112 		};
1113 
1114 		pipelineLayouts.push_back(makeSharedPtr(createPipelineLayout(vkd, device, &createInfo)));
1115 	}
1116 
1117 	return pipelineLayouts;
1118 }
1119 
createRenderPipelines(const DeviceInterface & vkd,VkDevice device,RenderPass renderPassInfo,VkRenderPass renderPass,vector<SharedPtrVkPipelineLayout> & pipelineLayouts,const BinaryCollection & binaryCollection,VkFormat format,deUint32 width,deUint32 height)1120 vector<SharedPtrVkPipeline> SubpassDependencyTestInstance::createRenderPipelines (const DeviceInterface&				vkd,
1121 																				  VkDevice								device,
1122 																				  RenderPass							renderPassInfo,
1123 																				  VkRenderPass							renderPass,
1124 																				  vector<SharedPtrVkPipelineLayout>&	pipelineLayouts,
1125 																				  const BinaryCollection&				binaryCollection,
1126 																				  VkFormat								format,
1127 																				  deUint32								width,
1128 																				  deUint32								height)
1129 {
1130 	vector<SharedPtrVkPipeline> pipelines;
1131 
1132 	for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
1133 	{
1134 		const Unique<VkShaderModule>				vertexShaderModule			(createShaderModule(vkd, device, binaryCollection.get("subpass-vert-" + de::toString(subpassNdx)), 0u));
1135 		const Unique<VkShaderModule>				fragmentShaderModule		(createShaderModule(vkd, device, binaryCollection.get("subpass-frag-" + de::toString(subpassNdx)), 0u));
1136 
1137 		const VkVertexInputBindingDescription		vertexBinding0				=
1138 		{
1139 			0u,							// deUint32					binding;
1140 			sizeof(Vec4),				// deUint32					strideInBytes;
1141 			VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputStepRate	stepRate;
1142 		};
1143 
1144 		VkVertexInputAttributeDescription			attr0						=
1145 		{
1146 			0u,								// deUint32	location;
1147 			0u,								// deUint32	binding;
1148 			VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format;
1149 			0u								// deUint32	offsetInBytes;
1150 		};
1151 
1152 		const VkPipelineVertexInputStateCreateInfo	vertexInputState			=
1153 		{
1154 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType
1155 			DE_NULL,													// const void*								pNext
1156 			(VkPipelineVertexInputStateCreateFlags)0u,					// VkPipelineVertexInputStateCreateFlags	flags
1157 			1u,															// uint32_t									vertexBindingDescriptionCount
1158 			&vertexBinding0,											// const VkVertexInputBindingDescription*	pVertexBindingDescriptions
1159 			1u,															// uint32_t									vertexAttributeDescriptionCount
1160 			&attr0														// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions
1161 		};
1162 
1163 		const VkStencilOpState						stencilOpState				=
1164 		{
1165 			VK_STENCIL_OP_KEEP,		// stencilFailOp
1166 			VK_STENCIL_OP_KEEP,		// stencilPassOp
1167 			VK_STENCIL_OP_KEEP,		// stencilDepthFailOp
1168 			VK_COMPARE_OP_ALWAYS,	// stencilCompareOp
1169 			0x0u,					// stencilCompareMask
1170 			0x0u,					// stencilWriteMask
1171 			0u						// stencilReference
1172 		};
1173 
1174 		const VkPipelineDepthStencilStateCreateInfo	depthStencilStateCreateInfo	=
1175 		{
1176 			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType
1177 			DE_NULL,													// const void*								pNext
1178 			0u,															// VkPipelineDepthStencilStateCreateFlags	flags
1179 			VK_TRUE,													// VkBool32									depthTestEnable
1180 			VK_TRUE,													// VkBool32									depthWriteEnable
1181 			VK_COMPARE_OP_LESS_OR_EQUAL,								// VkCompareOp								depthCompareOp
1182 			VK_FALSE,													// VkBool32									depthBoundsTestEnable
1183 			VK_TRUE,													// VkBool32									stencilTestEnable
1184 			stencilOpState,												// VkStencilOpState							front
1185 			stencilOpState,												// VkStencilOpState							back
1186 			0.0f,														// float									minDepthBounds
1187 			1.0f,														// float									maxDepthBounds
1188 		};
1189 
1190 		const std::vector<VkViewport>				viewports					(1, makeViewport(tcu::UVec2(width, height)));
1191 		const std::vector<VkRect2D>					scissors					(1, makeRect2D(tcu::UVec2(width, height)));
1192 		const VkPipelineLayout						layout						(**pipelineLayouts[subpassNdx]);
1193 		const VkPipelineDepthStencilStateCreateInfo	depthStencilCreateInfo		(isDepthStencilFormat(format)
1194 																					? depthStencilStateCreateInfo
1195 																					: VkPipelineDepthStencilStateCreateInfo());
1196 
1197 		pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(vkd,									// const DeviceInterface&							vk
1198 															   device,								// const VkDevice									device
1199 															   layout,								// const VkPipelineLayout							pipelineLayout
1200 															   *vertexShaderModule,					// const VkShaderModule								vertexShaderModule
1201 															   DE_NULL,								// const VkShaderModule								tessellationControlShaderModule
1202 															   DE_NULL,								// const VkShaderModule								tessellationEvalShaderModule
1203 															   DE_NULL,								// const VkShaderModule								geometryShaderModule
1204 															   *fragmentShaderModule,				// const VkShaderModule								fragmentShaderModule
1205 															   renderPass,							// const VkRenderPass								renderPass
1206 															   viewports,							// const std::vector<VkViewport>&					viewports
1207 															   scissors,							// const std::vector<VkRect2D>&						scissors
1208 															   VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology						topology
1209 															   (deUint32)subpassNdx,				// const deUint32									subpass
1210 															   0u,									// const deUint32									patchControlPoints
1211 															   &vertexInputState,					// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
1212 															   DE_NULL,								// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
1213 															   DE_NULL,								// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
1214 															   &depthStencilCreateInfo,				// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
1215 															   DE_NULL)));							// const VkPipelineDynamicStateCreateInfo*			pDynamicState
1216 	}
1217 
1218 	return pipelines;
1219 }
1220 
createFramebuffer(const DeviceInterface & vkd,VkDevice device,RenderPass renderPassInfo,VkRenderPass renderPass,vector<SharedPtrVkImageView> & dstImageViews,deUint32 width,deUint32 height)1221 Move<VkFramebuffer> SubpassDependencyTestInstance::createFramebuffer (const DeviceInterface&		vkd,
1222 																	  VkDevice						device,
1223 																	  RenderPass					renderPassInfo,
1224 																	  VkRenderPass					renderPass,
1225 																	  vector<SharedPtrVkImageView>&	dstImageViews,
1226 																	  deUint32						width,
1227 																	  deUint32						height)
1228 {
1229 	const size_t		attachmentCount		(renderPassInfo.getAttachments().size());
1230 	vector<VkImageView>	attachmentHandles;
1231 
1232 	for (deUint32 attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
1233 		attachmentHandles.push_back(**dstImageViews.at(attachmentNdx));
1234 
1235 	const VkFramebufferCreateInfo createInfo =
1236 	{
1237 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType
1238 		DE_NULL,									// const void*				pNext
1239 		0u,											// VkFramebufferCreateFlags	flags
1240 		renderPass,									// VkRenderPass				renderPass
1241 		(deUint32)attachmentCount,					// uint32_t					attachmentCount
1242 		attachmentHandles.data(),					// const VkImageView*		pAttachments
1243 		width,										// uint32_t					width
1244 		height,										// uint32_t					height
1245 		1u											// uint32_t					layers
1246 	};
1247 
1248 	return vk::createFramebuffer(vkd, device, &createInfo);
1249 }
1250 
createDescriptorSetLayouts(const DeviceInterface & vkd,VkDevice device,RenderPass renderPassInfo)1251 vector<SharedPtrVkDescriptorLayout> SubpassDependencyTestInstance::createDescriptorSetLayouts (const DeviceInterface&	vkd,
1252 																							   VkDevice					device,
1253 																							   RenderPass				renderPassInfo)
1254 {
1255 	vector<SharedPtrVkDescriptorLayout> layouts;
1256 
1257 	size_t attachmentCount = renderPassInfo.getAttachments().size();
1258 
1259 	for (size_t layoutNdx = 0; layoutNdx < attachmentCount - 1; layoutNdx++)
1260 	{
1261 		const VkDescriptorSetLayoutBinding		bindings	=
1262 		{
1263 				0u,										// uint32_t				binding
1264 				VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,	// VkDescriptorType		descriptorType
1265 				1u,										// uint32_t				descriptorCount
1266 				VK_SHADER_STAGE_FRAGMENT_BIT,			// VkShaderStageFlags	stageFlags
1267 				DE_NULL									// const VkSampler*		pImmutableSamplers
1268 		};
1269 
1270 		const VkDescriptorSetLayoutCreateInfo	createInfo	=
1271 		{
1272 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType						sType
1273 			DE_NULL,												// const void*							pNext
1274 			0u,														// VkDescriptorSetLayoutCreateFlags		flags
1275 			1u,														// uint32_t								bindingCount
1276 			&bindings												// const VkDescriptorSetLayoutBinding*	pBindings
1277 		};
1278 
1279 		layouts.push_back(makeSharedPtr(createDescriptorSetLayout(vkd, device, &createInfo)));
1280 	}
1281 
1282 	return layouts;
1283 }
1284 
createDescriptorSets(const DeviceInterface & vkd,VkDevice device,VkFormat format,vector<SharedPtrVkDescriptorPool> & pools,vector<SharedPtrVkDescriptorLayout> & layouts,vector<SharedPtrVkImageView> & imageViews)1285 vector<SharedPtrVkDescriptorSet> SubpassDependencyTestInstance::createDescriptorSets (const DeviceInterface&				vkd,
1286 																					  VkDevice								device,
1287 																					  VkFormat								format,
1288 																					  vector<SharedPtrVkDescriptorPool>&	pools,
1289 																					  vector<SharedPtrVkDescriptorLayout>&	layouts,
1290 																					  vector<SharedPtrVkImageView>&			imageViews)
1291 {
1292 	vector<SharedPtrVkDescriptorSet> descriptorSets;
1293 
1294 	for (size_t setNdx = 0; setNdx < layouts.size(); setNdx++)
1295 	{
1296 		const VkDescriptorSetAllocateInfo allocateInfo =
1297 		{
1298 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,	// VkStructureType				sType
1299 			DE_NULL,										// const void*					pNext
1300 			**pools[setNdx],								// VkDescriptorPool				descriptorPool
1301 			1u,												// uint32_t						descriptorSetCount
1302 			&**layouts[setNdx]								// const VkDescriptorSetLayout*	pSetLayouts
1303 		};
1304 
1305 		descriptorSets.push_back(makeSharedPtr(allocateDescriptorSet(vkd, device, &allocateInfo)));
1306 
1307 		{
1308 			VkImageLayout imageLayout				= isDepthStencilFormat(format)
1309 														? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
1310 														: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1311 
1312 			const VkDescriptorImageInfo	imageInfo	=
1313 			{
1314 				DE_NULL,				// VkSampler		sampler
1315 				**imageViews[setNdx],	// VkImageView		imageView
1316 				imageLayout				// VkImageLayout	imageLayout
1317 			};
1318 
1319 			const VkWriteDescriptorSet	write		=
1320 			{
1321 				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType
1322 				DE_NULL,								// const void*						pNext
1323 				**descriptorSets[setNdx],				// VkDescriptorSet					dstSet
1324 				0u,										// uint32_t							dstBinding
1325 				0u,										// uint32_t							dstArrayElement
1326 				1u,										// uint32_t							descriptorCount
1327 				VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,	// VkDescriptorType					descriptorType
1328 				&imageInfo,								// const VkDescriptorImageInfo*		pImageInfo
1329 				DE_NULL,								// const VkDescriptorBufferInfo*	pBufferInfo
1330 				DE_NULL									// const VkBufferView*				pTexelBufferView
1331 			};
1332 
1333 			vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
1334 		}
1335 	}
1336 
1337 	return descriptorSets;
1338 }
1339 
getRepresentableDepthChannel(const ConstPixelBufferAccess & access)1340 tcu::TextureLevel SubpassDependencyTestInstance::getRepresentableDepthChannel (const ConstPixelBufferAccess& access)
1341 {
1342 	tcu::TextureLevel depthChannel (mapVkFormat(VK_FORMAT_R8G8B8_UNORM), access.getWidth(), access.getHeight());
1343 
1344 	for (int y = 0; y < access.getHeight(); y++)
1345 	for (int x = 0; x < access.getWidth(); x++)
1346 		depthChannel.getAccess().setPixel(tcu::Vec4(access.getPixDepth(x, y)), x, y);
1347 
1348 	return depthChannel;
1349 }
1350 
verifyDepth(const ConstPixelBufferAccess & reference,const ConstPixelBufferAccess & result,const float threshold)1351 bool SubpassDependencyTestInstance::verifyDepth (const ConstPixelBufferAccess&	reference,
1352 												 const ConstPixelBufferAccess&	result,
1353 												 const float					threshold)
1354 {
1355 	tcu::TestLog& log (m_context.getTestContext().getLog());
1356 
1357 	return tcu::floatThresholdCompare(log,										// log
1358 									  "Depth channel",							// imageSetName
1359 									  "Depth compare",							// imageSetDesc
1360 									  getRepresentableDepthChannel(reference),	// reference
1361 									  getRepresentableDepthChannel(result),		// result
1362 									  Vec4(threshold),							// threshold
1363 									  tcu::COMPARE_LOG_RESULT);					// logMode
1364 }
1365 
verifyStencil(const ConstPixelBufferAccess & reference,const ConstPixelBufferAccess & result)1366 bool SubpassDependencyTestInstance::verifyStencil (const ConstPixelBufferAccess&	reference,
1367 												   const ConstPixelBufferAccess&	result)
1368 {
1369 	tcu::TextureLevel	stencilErrorImage	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight());
1370 	tcu::TestLog&		log					(m_context.getTestContext().getLog());
1371 	bool				stencilOk			(DE_TRUE);
1372 
1373 	for (int y = 0; y < result.getHeight(); y++)
1374 	for (int x = 0; x < result.getWidth(); x++)
1375 	{
1376 		if (result.getPixStencil(x, y) != reference.getPixStencil(x, y))
1377 		{
1378 			stencilErrorImage.getAccess().setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
1379 			stencilOk = DE_FALSE;
1380 		}
1381 		else
1382 			stencilErrorImage.getAccess().setPixel(Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
1383 	}
1384 
1385 	log << tcu::TestLog::ImageSet("Stencil compare", "Stencil compare")
1386 		<< tcu::TestLog::Image("Result stencil channel", "Result stencil channel", result)
1387 		<< tcu::TestLog::Image("Reference stencil channel", "Reference stencil channel", reference);
1388 
1389 	if (!stencilOk)
1390 		log << tcu::TestLog::Image("Stencil error mask", "Stencil error mask", stencilErrorImage);
1391 
1392 	log << tcu::TestLog::EndImageSet;
1393 
1394 	return stencilOk;
1395 }
1396 
iterate(void)1397 tcu::TestStatus SubpassDependencyTestInstance::iterate (void)
1398 {
1399 	switch (m_renderPassType)
1400 	{
1401 		case RENDERPASS_TYPE_LEGACY:
1402 			return iterateInternal<RenderpassSubpass1>();
1403 		case RENDERPASS_TYPE_RENDERPASS2:
1404 			return iterateInternal<RenderpassSubpass2>();
1405 		default:
1406 			TCU_THROW(InternalError, "Impossible");
1407 	}
1408 }
1409 
truncateCoord(int dim,int subPixelBits,float f)1410 static float truncateCoord(int dim, int subPixelBits, float f)
1411 {
1412 	const float scale = (float)(dim << subPixelBits);
1413 	const float coord = deFloatFloor(f * scale) / scale;
1414 
1415 	return coord;
1416 }
1417 
1418 template<typename RenderpassSubpass>
iterateInternal(void)1419 tcu::TestStatus SubpassDependencyTestInstance::iterateInternal (void)
1420 {
1421 	de::Random											rand					(5);
1422 	const DeviceInterface&								vkd						(m_context.getDeviceInterface());
1423 	const Unique<VkCommandBuffer>						commandBuffer			(allocateCommandBuffer(vkd, m_context.getDevice(), *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1424 	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo		(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
1425 	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo			(DE_NULL);
1426 	const size_t										attachmentCount			(m_renderPassInfo.getAttachments().size());
1427 	const size_t										subpassCount			(m_renderPassInfo.getSubpasses().size());
1428 	vector<VkClearValue>								clearValues;
1429 	vector<Vec4>										vertexData;
1430 
1431 	beginCommandBuffer(vkd, *commandBuffer);
1432 
1433 	// Begin render pass
1434 	{
1435 		VkRect2D					renderArea			=
1436 		{
1437 			{ 0u, 0u },				// VkOffset2D	offset
1438 			{ m_width, m_height }	// VkExtent2D	extent
1439 		};
1440 
1441 		for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
1442 			clearValues.push_back(isDepthStencilFormat(m_format) ? makeClearValueDepthStencil(1.0f, 255u) : makeClearValueColor(Vec4(1.0f, 0.0f, 0.0f, 1.0f)));
1443 
1444 		const VkRenderPassBeginInfo	beginInfo			=
1445 		{
1446 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType
1447 			DE_NULL,									// const void*			pNext
1448 			*m_renderPass,								// VkRenderPass			renderPass
1449 			*m_framebuffer,								// VkFramebuffer		framebuffer
1450 			renderArea,									// VkRect2D				renderArea
1451 			(deUint32)attachmentCount,					// uint32_t				clearValueCount
1452 			clearValues.data()							// const VkClearValue*	pClearValues
1453 		};
1454 
1455 		RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
1456 	}
1457 
1458 	// Generate vertices for 128 triangles with pseudorandom positions and depths values
1459 	for (int primitiveNdx = 0; primitiveNdx < 128; primitiveNdx++)
1460 	{
1461 		float primitiveDepth = rand.getFloat();
1462 
1463 		for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
1464 		{
1465 			const int subPixelBits = m_context.getDeviceProperties().limits.subPixelPrecisionBits;
1466 
1467 			float x = 2.0f * truncateCoord(m_width,  subPixelBits, rand.getFloat()) - 1.0f;
1468 			float y = 2.0f * truncateCoord(m_height, subPixelBits, rand.getFloat()) - 1.0f;
1469 
1470 			vertexData.push_back(Vec4(x, y, primitiveDepth, 1.0f));
1471 		}
1472 	}
1473 
1474 	const size_t										singleVertexDataSize	= sizeof(Vec4);
1475 	const size_t										vertexCount				= vertexData.size();
1476 	const size_t										vertexDataSize			= vertexCount * singleVertexDataSize;
1477 	const deUint32										queueFamilyIndices		= m_context.getUniversalQueueFamilyIndex();
1478 
1479 	const VkBufferCreateInfo							vertexBufferParams		=
1480 	{
1481 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	//	VkStructureType		sType;
1482 		DE_NULL,								//	const void*			pNext;
1483 		0u,										//	VkBufferCreateFlags	flags;
1484 		(VkDeviceSize)vertexDataSize,			//	VkDeviceSize		size;
1485 		VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		//	VkBufferUsageFlags	usage;
1486 		VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode		sharingMode;
1487 		1u,										//	deUint32			queueFamilyCount;
1488 		&queueFamilyIndices,					//	const deUint32*		pQueueFamilyIndices;
1489 	};
1490 
1491 	const Unique<VkBuffer>								vertexBuffer			(createBuffer(vkd, m_context.getDevice(), &vertexBufferParams));
1492 	const de::UniquePtr<Allocation>						vertexBufferMemory		(m_context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vkd, m_context.getDevice(), *vertexBuffer), MemoryRequirement::HostVisible));
1493 
1494 	VK_CHECK(vkd.bindBufferMemory(m_context.getDevice(), *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
1495 
1496 	const VkDeviceSize bindingOffset = 0;
1497 	vkd.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
1498 
1499 	for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
1500 	{
1501 		if (subpassNdx > 0)
1502 		{
1503 			RenderpassSubpass::cmdNextSubpass(vkd, *commandBuffer, &subpassBeginInfo, &subpassEndInfo);
1504 			vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_renderPipelineLayouts[subpassNdx], 0, 1, &**m_subpassDescriptorSets[subpassNdx - 1], 0, DE_NULL);
1505 		}
1506 
1507 		vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_renderPipelines[subpassNdx]);
1508 
1509 		if (subpassNdx == 0)
1510 		{
1511 			// Upload vertex data
1512 			{
1513 				void* vertexBufPtr = vertexBufferMemory->getHostPtr();
1514 				deMemcpy(vertexBufPtr, vertexData.data(), vertexDataSize);
1515 				flushAlloc(vkd, m_context.getDevice(), *vertexBufferMemory);
1516 			}
1517 
1518 			vkd.cmdDraw(*commandBuffer, (deUint32)vertexData.size(), 1u, 0u, 0u);
1519 		}
1520 		else
1521 			vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1522 	}
1523 
1524 	RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
1525 
1526 	// Memory barrier between rendering and copy
1527 	{
1528 		const VkImageAspectFlags	imageAspectFlags		= isDepthStencilFormat(m_format)
1529 																? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
1530 		const VkAccessFlags			srcAccessMask			= isDepthStencilFormat(m_format)
1531 																? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT : VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1532 		const VkImageLayout			oldLayout				= isDepthStencilFormat(m_format)
1533 																? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1534 		const VkPipelineStageFlags	srcStageMask			= isDepthStencilFormat(m_format)
1535 																? VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT : VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
1536 
1537 		VkImageSubresourceRange		imageSubresourceRange	=
1538 		{
1539 			imageAspectFlags,	// VkImageAspectFlags	aspectMask
1540 			0u,					// uint32_t				baseMipLevel
1541 			1u,					// uint32_t				levelCount
1542 			0u,					// uint32_t				baseArrayLayer
1543 			1u					// uint32_t				layerCount
1544 		};
1545 
1546 		const VkImageMemoryBarrier	barrier					=
1547 		{
1548 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType
1549 			DE_NULL,								// const void*				pNext
1550 			srcAccessMask,							// VkAccessFlags			srcAccessMask
1551 			VK_ACCESS_TRANSFER_READ_BIT,			// VkAccessFlags			dstAccessMask
1552 			oldLayout,								// VkImageLayout			oldLayout
1553 			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,	// VkImageLayout			newLayout
1554 			VK_QUEUE_FAMILY_IGNORED,				// uint32_t					srcQueueFamilyIndex
1555 			VK_QUEUE_FAMILY_IGNORED,				// uint32_t					dstQueueFamilyIndex
1556 			**m_images[attachmentCount - 1],		// VkImage					image
1557 			imageSubresourceRange					// VkImageSubresourceRange	subresourceRange
1558 		};
1559 
1560 		vkd.cmdPipelineBarrier(*commandBuffer, srcStageMask, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
1561 	}
1562 
1563 	// Copy image memory to buffer
1564 	{
1565 		if (isDepthStencilFormat(m_format))
1566 		{
1567 			// Copy depth
1568 			const VkImageSubresourceLayers subresourceLayersDepth	=
1569 			{
1570 				VK_IMAGE_ASPECT_DEPTH_BIT,	// VkImageAspectFlags	aspectMask
1571 				0u,							// deUint32				mipLevel
1572 				0u,							// deUint32				baseArrayLayer
1573 				1u							// deUint32				layerCount
1574 			};
1575 
1576 			const VkBufferImageCopy			regionDepth				=
1577 			{
1578 				0u,							// VkDeviceSize				bufferOffset
1579 				0u,							// uint32_t					bufferRowLength
1580 				0u,							// uint32_t					bufferImageHeight
1581 				subresourceLayersDepth,		// VkImageSubresourceLayers	imageSubresource
1582 				{ 0u, 0u, 0u },				// VkOffset3D				imageOffset
1583 				{ m_width, m_height, 1u }	// VkExtent3D				imageExtent
1584 			};
1585 
1586 			vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[attachmentCount - 1], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_primaryBuffer, 1u, &regionDepth);
1587 
1588 			// Copy stencil
1589 			const VkImageSubresourceLayers subresourceLayersStencil	=
1590 			{
1591 				VK_IMAGE_ASPECT_STENCIL_BIT,	// VkImageAspectFlags	aspectMask
1592 				0u,								// deUint32				mipLevel
1593 				0u,								// deUint32				baseArrayLayer
1594 				1u								// deUint32				layerCount
1595 			};
1596 
1597 			const VkBufferImageCopy			regionStencil			=
1598 			{
1599 				0u,							// VkDeviceSize				bufferOffset
1600 				0u,							// uint32_t					bufferRowLength
1601 				0u,							// uint32_t					bufferImageHeight
1602 				subresourceLayersStencil,	// VkImageSubresourceLayers	imageSubresource
1603 				{ 0u, 0u, 0u },				// VkOffset3D				imageOffset
1604 				{ m_width, m_height, 1u }	// VkExtent3D				imageExtent
1605 			};
1606 
1607 			vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[attachmentCount - 1], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_secondaryBuffer, 1u, &regionStencil);
1608 		}
1609 		else
1610 		{
1611 			// Copy color
1612 			const VkImageSubresourceLayers imageSubresourceLayers	=
1613 			{
1614 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask
1615 				0u,							// deUint32				mipLevel
1616 				0u,							// deUint32				baseArrayLayer
1617 				1u							// deUint32				layerCount
1618 			};
1619 
1620 			const VkBufferImageCopy			region					=
1621 			{
1622 				0u,							// VkDeviceSize				bufferOffset
1623 				0u,							// uint32_t					bufferRowLength
1624 				0u,							// uint32_t					bufferImageHeight
1625 				imageSubresourceLayers,		// VkImageSubresourceLayers	imageSubresource
1626 				{ 0u, 0u, 0u },				// VkOffset3D				imageOffset
1627 				{ m_width, m_height, 1u }	// VkExtent3D				imageExtent
1628 			};
1629 
1630 			vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[attachmentCount - 1], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_primaryBuffer, 1u, &region);
1631 		}
1632 	}
1633 
1634 	// Memory barrier between copy and host access
1635 	{
1636 		const VkBufferMemoryBarrier barrier		=
1637 		{
1638 			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType
1639 			DE_NULL,									// const void*		pNext
1640 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask
1641 			VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask
1642 			VK_QUEUE_FAMILY_IGNORED,					// uint32_t			srcQueueFamilyIndex
1643 			VK_QUEUE_FAMILY_IGNORED,					// uint32_t			dstQueueFamilyIndex
1644 			*m_primaryBuffer,							// VkBuffer			buffer
1645 			0u,											// VkDeviceSize		offset
1646 			VK_WHOLE_SIZE								// VkDeviceSize		size
1647 		};
1648 
1649 		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
1650 
1651 		if (isDepthStencilFormat(m_format))
1652 		{
1653 			const VkBufferMemoryBarrier stencilBarrier =
1654 			{
1655 				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType
1656 				DE_NULL,									// const void*		pNext
1657 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask
1658 				VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask
1659 				VK_QUEUE_FAMILY_IGNORED,					// uint32_t			srcQueueFamilyIndex
1660 				VK_QUEUE_FAMILY_IGNORED,					// uint32_t			dstQueueFamilyIndex
1661 				*m_secondaryBuffer,							// VkBuffer			buffer
1662 				0u,											// VkDeviceSize		offset
1663 				VK_WHOLE_SIZE								// VkDeviceSize		size
1664 			};
1665 
1666 			vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &stencilBarrier, 0u, DE_NULL);
1667 		}
1668 	}
1669 
1670 	endCommandBuffer(vkd, *commandBuffer);
1671 	submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
1672 	invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_primaryBufferMemory->getMemory(), m_primaryBufferMemory->getOffset(), VK_WHOLE_SIZE);
1673 	invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_secondaryBufferMemory->getMemory(), m_secondaryBufferMemory->getOffset(), VK_WHOLE_SIZE);
1674 
1675 	// Verify result
1676 	{
1677 		const tcu::TextureFormat format (mapVkFormat(m_format));
1678 
1679 		if (isDepthStencilFormat(m_format))
1680 		{
1681 			const void* const					ptrDepth				(m_primaryBufferMemory->getHostPtr());
1682 			const void* const					ptrStencil				(m_secondaryBufferMemory->getHostPtr());
1683 			tcu::TextureLevel					reference				(format, m_width, m_height);
1684 			tcu::TextureLevel					colorBuffer				(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM), m_width, m_height);
1685 			const tcu::ConstPixelBufferAccess	resultDepthAccess		(getDepthCopyFormat(m_format), m_width, m_height, 1, ptrDepth);
1686 			const tcu::ConstPixelBufferAccess	resultStencilAccess		(getStencilCopyFormat(m_format), m_width, m_height, 1, ptrStencil);
1687 			const PixelBufferAccess				referenceDepthAccess	(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH));
1688 			const PixelBufferAccess				referenceStencilAccess	(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL));
1689 
1690 			tcu::clearDepth(referenceDepthAccess, 1.0f);
1691 			tcu::clearStencil(referenceStencilAccess, 255);
1692 
1693 			// Setup and run reference renderer
1694 			{
1695 				const DepthVertShader					vertShader;
1696 				const DepthFragShader					fragShader;
1697 				const rr::Renderer						renderer;
1698 				const rr::Program						program				(&vertShader, &fragShader);
1699 				const rr::MultisamplePixelBufferAccess	depthBuffer			(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(referenceDepthAccess));
1700 				const rr::MultisamplePixelBufferAccess	colorBufferAccess	(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(colorBuffer.getAccess()));
1701 				const rr::RenderTarget					renderTarget		(rr::MultisamplePixelBufferAccess(colorBufferAccess), depthBuffer, rr::MultisamplePixelBufferAccess());
1702 				const rr::PrimitiveType					primitiveType		(rr::PRIMITIVETYPE_TRIANGLES);
1703 				const rr::PrimitiveList					primitiveList		(rr::PrimitiveList(primitiveType, (deUint32)vertexData.size(), 0));
1704 				rr::RenderState							renderState			((rr::ViewportState(depthBuffer)));
1705 
1706 				const rr::VertexAttrib vertices			= rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &vertexData[0]);
1707 
1708 				renderState.fragOps.depthTestEnabled	= DE_TRUE;
1709 				renderState.fragOps.depthFunc			= rr::TESTFUNC_LEQUAL;
1710 
1711 				renderer.draw(rr::DrawCommand(renderState,
1712 											  renderTarget,
1713 											  program,
1714 											  1u,
1715 											  &vertices,
1716 											  primitiveList));
1717 			}
1718 
1719 			for (size_t subpassNdx = 0; subpassNdx < subpassCount - 1; subpassNdx++)
1720 			{
1721 				for (int y = 0; y < reference.getHeight(); y++)
1722 				for (int x = 0; x < reference.getWidth(); x++)
1723 					reference.getAccess().setPixDepth(reference.getAccess().getPixDepth(x, y) - 0.02f, x, y);
1724 			}
1725 
1726 			// Threshold size of subpass count multiplied by the minimum representable difference is allowed for depth compare
1727 			const float							depthThreshold			((float)subpassCount * (1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(
1728 																			resultDepthAccess.getFormat()).cast<deUint32>()) - 1u).cast<float>().x()));
1729 
1730 			if (!verifyDepth(reference.getAccess(), resultDepthAccess, depthThreshold))
1731 				m_resultCollector.fail("Depth compare failed.");
1732 
1733 			if (!verifyStencil(referenceStencilAccess, resultStencilAccess))
1734 				m_resultCollector.fail("Stencil compare failed.");
1735 		}
1736 		else
1737 			DE_FATAL("Not implemented");
1738 	}
1739 
1740 	return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1741 }
1742 
1743 // Shader programs for testing dependencies between render pass instances
1744 struct ExternalPrograms
1745 {
initvkt::__anon104c10a40111::ExternalPrograms1746 	void init (vk::SourceCollections& dst, ExternalTestConfig testConfig) const
1747 	{
1748 		for (size_t renderPassNdx = 0; renderPassNdx < testConfig.renderPasses.size(); renderPassNdx++)
1749 		{
1750 			dst.glslSources.add("quad-vert-" + de::toString(renderPassNdx)) << glu::VertexSource(
1751 				"#version 450\n"
1752 				"layout(location = 0) out highp vec2 vtxTexCoords;\n"
1753 				"highp float;\n"
1754 				"void main (void)\n"
1755 				"{\n"
1756 				"    vec4 position;"
1757 				"    position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
1758 				"                    ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
1759 				"    gl_Position = position;\n"
1760 				"	vtxTexCoords = position.xy / 2.0 + vec2(0.5);"
1761 				"}\n");
1762 
1763 			// First pass renders four quads of different color
1764 			if (renderPassNdx == 0)
1765 			{
1766 				dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
1767 					"#version 450\n"
1768 					"layout(location = 0) in highp vec2 vtxTexCoords;\n"
1769 					"layout(location = 0) out highp vec4 o_color;\n"
1770 					"void main (void)\n"
1771 					"{\n"
1772 					"    if (gl_FragCoord.x <= " + de::toString(testConfig.imageSize.x() / 2) + " && gl_FragCoord.y <= " + de::toString(testConfig.imageSize.y() / 2) + ")\n"
1773 					"        o_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
1774 					"    else if (gl_FragCoord.x > " + de::toString(testConfig.imageSize.x() / 2) + " && gl_FragCoord.y <= " + de::toString(testConfig.imageSize.y() / 2) + ")\n"
1775 					"        o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
1776 					"    else if (gl_FragCoord.x <= " + de::toString(testConfig.imageSize.x() / 2) + " && gl_FragCoord.y > " + de::toString(testConfig.imageSize.y() / 2) + ")\n"
1777 					"        o_color = vec4(0.0, 0.0, 1.0, 1.0);\n"
1778 					"    else\n"
1779 					"        o_color = vec4(0.0, 0.0, 0.0, 1.0);\n"
1780 					""
1781 					"}\n");
1782 			}
1783 			else
1784 			{
1785 				if (renderPassNdx % 2 == 0)
1786 				{
1787 					// Blur previous pass horizontally
1788 					dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
1789 						"#version 450\n"
1790 						"layout(binding = 0) uniform sampler2D previousPass;\n"
1791 						"layout(location = 0) in highp vec2 vtxTexCoords;\n"
1792 						"layout(location = 0) out highp vec4 o_color;\n"
1793 						"void main (void)\n"
1794 						"{\n"
1795 						"    vec2 step = vec2(1.0 / " + de::toString(testConfig.imageSize.x()) + ", 1.0 / " + de::toString(testConfig.imageSize.y()) + ");\n"
1796 						"    vec2 minCoord = vec2(0.0, 0.0);\n"
1797 						"    vec2 maxCoord = vec2(1.0, 1.0);\n"
1798 						"    vec4 blurColor = vec4(0.0);\n"
1799 						"    for(int sampleNdx = 0; sampleNdx < " + de::toString(testConfig.blurKernel + 1) + "; sampleNdx++)\n"
1800 						"    {\n"
1801 						"        vec2 sampleCoord = vec2((vtxTexCoords.x - " + de::toString(testConfig.blurKernel / 2) + " * step.x) + step.x * sampleNdx, vtxTexCoords.y);\n"
1802 						"        blurColor += 0.12 * texture(previousPass, clamp(sampleCoord, minCoord, maxCoord));\n"
1803 						"    }\n"
1804 						"    o_color = blurColor;\n"
1805 						"}\n");
1806 				}
1807 				else
1808 				{
1809 					// Blur previous pass vertically
1810 					dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
1811 						"#version 450\n"
1812 						"layout(binding = 0) uniform highp sampler2D previousPass;\n"
1813 						"layout(location = 0) in highp vec2 vtxTexCoords;\n"
1814 						"layout(location = 0) out highp vec4 o_color;\n"
1815 						"void main (void)\n"
1816 						"{\n"
1817 						"    vec2 step = vec2(1.0 / " + de::toString(testConfig.imageSize.x()) + ", 1.0 / " + de::toString(testConfig.imageSize.y()) + ");\n"
1818 						"    vec2 minCoord = vec2(0.0, 0.0);\n"
1819 						"    vec2 maxCoord = vec2(1.0, 1.0);\n"
1820 						"    vec4 blurColor = vec4(0.0);\n"
1821 						"    for(int sampleNdx = 0; sampleNdx < " + de::toString(testConfig.blurKernel + 1) + "; sampleNdx++)\n"
1822 						"    {\n"
1823 						"        vec2 sampleCoord = vec2(vtxTexCoords.x, (vtxTexCoords.y - " + de::toString(testConfig.blurKernel / 2) + " * step.y) + step.y * sampleNdx);\n"
1824 						"        blurColor += 0.12 * texture(previousPass, clamp(sampleCoord, minCoord, maxCoord));\n"
1825 						"    }\n"
1826 						"    o_color = blurColor;\n"
1827 						"}\n");
1828 				}
1829 			}
1830 		}
1831 	}
1832 };
1833 
1834 // Shader programs for testing dependencies between subpasses
1835 struct SubpassPrograms
1836 {
initvkt::__anon104c10a40111::SubpassPrograms1837 	void init (vk::SourceCollections& dst, SubpassTestConfig testConfig) const
1838 	{
1839 		size_t subpassCount = testConfig.renderPass.getSubpasses().size();
1840 
1841 		for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
1842 		{
1843 			if (subpassNdx == 0)
1844 			{
1845 				dst.glslSources.add("subpass-vert-" + de::toString(subpassNdx)) << glu::VertexSource(
1846 				"#version 450\n"
1847 				"highp float;\n"
1848 				"layout(location = 0) in highp vec4 position;\n"
1849 				"void main (void)\n"
1850 				"{\n"
1851 				"    gl_Position = position;\n"
1852 				"}\n");
1853 			}
1854 			else
1855 			{
1856 				dst.glslSources.add("subpass-vert-" + de::toString(subpassNdx)) << glu::VertexSource(
1857 					"#version 450\n"
1858 					"highp float;\n"
1859 					"void main (void)\n"
1860 					"{\n"
1861 					"    vec4 position;"
1862 					"    position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
1863 					"                    ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
1864 					"    gl_Position = position;\n"
1865 					"}\n");
1866 			}
1867 
1868 			if (isDepthStencilFormat(testConfig.format))
1869 			{
1870 				if (subpassNdx == 0)
1871 				{
1872 					// Empty fragment shader: Fragment depth unmodified.
1873 					dst.glslSources.add("subpass-frag-" + de::toString(subpassNdx)) << glu::FragmentSource(
1874 						"#version 450\n"
1875 						"void main (void)\n"
1876 						"{\n"
1877 						"}\n");
1878 				}
1879 				else
1880 				{
1881 					// Use fragment depth from previous depth rendering result.
1882 					dst.glslSources.add("subpass-frag-" + de::toString(subpassNdx)) << glu::FragmentSource(
1883 						"#version 450\n"
1884 						"layout (input_attachment_index = 0, binding = 0) uniform subpassInput depthStencil;\n"
1885 						"void main (void)\n"
1886 						"{\n"
1887 						"    float inputDepth = subpassLoad(depthStencil).x;\n"
1888 						"    gl_FragDepth = inputDepth - 0.02;\n"
1889 						"}\n");
1890 				}
1891 			}
1892 			else
1893 				DE_FATAL("Unimplemented");
1894 		}
1895 	}
1896 };
1897 
formatToName(VkFormat format)1898 std::string formatToName (VkFormat format)
1899 {
1900 	const std::string	formatStr	= de::toString(format);
1901 	const std::string	prefix		= "VK_FORMAT_";
1902 
1903 	DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
1904 
1905 	return de::toLower(formatStr.substr(prefix.length()));
1906 }
1907 
initTests(tcu::TestCaseGroup * group,const RenderPassType renderPassType)1908 void initTests (tcu::TestCaseGroup* group, const RenderPassType renderPassType)
1909 {
1910 	tcu::TestContext& testCtx(group->getTestContext());
1911 
1912 	// Test external subpass dependencies
1913 	{
1914 		const deUint32	renderPassCounts[]	= { 2u, 3u, 5u};
1915 
1916 		const UVec2		renderSizes[]		=
1917 		{
1918 			UVec2(64, 64),
1919 			UVec2(128, 128),
1920 			UVec2(512, 512)
1921 		};
1922 
1923 		de::MovePtr<tcu::TestCaseGroup>	externalGroup	(new tcu::TestCaseGroup(testCtx, "external_subpass", "external_subpass"));
1924 
1925 		for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
1926 		{
1927 			string groupName	("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" + de::toString(renderSizes[renderSizeNdx].y()));
1928 			de::MovePtr<tcu::TestCaseGroup>	renderSizeGroup	(new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupName.c_str()));
1929 
1930 			for (size_t renderPassCountNdx = 0; renderPassCountNdx < DE_LENGTH_OF_ARRAY(renderPassCounts); renderPassCountNdx++)
1931 			{
1932 				vector<RenderPass>	renderPasses;
1933 
1934 				for (size_t renderPassNdx = 0; renderPassNdx < renderPassCounts[renderPassCountNdx]; renderPassNdx++)
1935 				{
1936 					vector<Attachment>			attachments;
1937 					vector<AttachmentReference>	colorAttachmentReferences;
1938 
1939 					const VkFormat				format				(VK_FORMAT_R8G8B8A8_UNORM);
1940 					const VkSampleCountFlagBits	sampleCount			(VK_SAMPLE_COUNT_1_BIT);
1941 					const VkAttachmentLoadOp	loadOp				(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
1942 					const VkAttachmentStoreOp	storeOp				(VK_ATTACHMENT_STORE_OP_STORE);
1943 					const VkAttachmentLoadOp	stencilLoadOp		(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
1944 					const VkAttachmentStoreOp	stencilStoreOp		(VK_ATTACHMENT_STORE_OP_DONT_CARE);
1945 					const VkImageLayout			initialLayout		(VK_IMAGE_LAYOUT_UNDEFINED);
1946 					const VkImageLayout			finalLayout			(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1947 					const VkImageLayout			subpassLayout		(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
1948 
1949 					attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalLayout));
1950 					colorAttachmentReferences.push_back(AttachmentReference((deUint32)0, subpassLayout));
1951 
1952 					const VkImageLayout			depthStencilLayout	(VK_IMAGE_LAYOUT_GENERAL);
1953 					const vector<Subpass>		subpasses			(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(),
1954 																		AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<deUint32>()));
1955 					vector<SubpassDependency>	deps;
1956 
1957 					deps.push_back(SubpassDependency(VK_SUBPASS_EXTERNAL,										// deUint32				srcPass
1958 													 0,															// deUint32				dstPass
1959 													 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,				// VkPipelineStageFlags	srcStageMask
1960 													 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,						// VkPipelineStageFlags	dstStageMask
1961 													 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,						// VkAccessFlags		srcAccessMask
1962 													 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,	// VkAccessFlags		dstAccessMask
1963 													 0));														// VkDependencyFlags	flags
1964 
1965 					deps.push_back(SubpassDependency(0,															// deUint32				srcPass
1966 													 VK_SUBPASS_EXTERNAL,										// deUint32				dstPass
1967 													 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,						// VkPipelineStageFlags	srcStageMask
1968 													 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,				// VkPipelineStageFlags	dstStageMask
1969 													 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,	// VkAccessFlags		srcAccessMask
1970 													 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,						// VkAccessFlags		dstAccessMask
1971 													 0));														// VkDependencyFlags	flags
1972 
1973 					RenderPass					renderPass			(attachments, subpasses, deps);
1974 
1975 					renderPasses.push_back(renderPass);
1976 				}
1977 
1978 				const deUint32				blurKernel	(12u);
1979 				const ExternalTestConfig	testConfig	(VK_FORMAT_R8G8B8A8_UNORM, renderSizes[renderSizeNdx], renderPasses, renderPassType, blurKernel);
1980 				const string				testName	("render_passes_" + de::toString(renderPassCounts[renderPassCountNdx]));
1981 
1982 				renderSizeGroup->addChild(new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
1983 			}
1984 
1985 			externalGroup->addChild(renderSizeGroup.release());
1986 		}
1987 
1988 		group->addChild(externalGroup.release());
1989 	}
1990 
1991 	// Test implicit subpass dependencies
1992 	{
1993 		const deUint32					renderPassCounts[]		= { 2u, 3u, 5u };
1994 
1995 		de::MovePtr<tcu::TestCaseGroup>	implicitGroup			(new tcu::TestCaseGroup(testCtx, "implicit_dependencies", "implicit_dependencies"));
1996 
1997 		for (size_t renderPassCountNdx = 0; renderPassCountNdx < DE_LENGTH_OF_ARRAY(renderPassCounts); renderPassCountNdx++)
1998 		{
1999 			vector<RenderPass> renderPasses;
2000 
2001 			for (size_t renderPassNdx = 0; renderPassNdx < renderPassCounts[renderPassCountNdx]; renderPassNdx++)
2002 			{
2003 				vector<Attachment>			attachments;
2004 				vector<AttachmentReference>	colorAttachmentReferences;
2005 
2006 				const VkFormat				format					(VK_FORMAT_R8G8B8A8_UNORM);
2007 				const VkSampleCountFlagBits	sampleCount				(VK_SAMPLE_COUNT_1_BIT);
2008 				const VkAttachmentLoadOp	loadOp					(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
2009 				const VkAttachmentStoreOp	storeOp					(VK_ATTACHMENT_STORE_OP_STORE);
2010 				const VkAttachmentLoadOp	stencilLoadOp			(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
2011 				const VkAttachmentStoreOp	stencilStoreOp			(VK_ATTACHMENT_STORE_OP_DONT_CARE);
2012 				const VkImageLayout			initialLayout			(VK_IMAGE_LAYOUT_UNDEFINED);
2013 				const VkImageLayout			finalLayout				(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
2014 				const VkImageLayout			subpassLayout			(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
2015 
2016 				attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalLayout));
2017 				colorAttachmentReferences.push_back(AttachmentReference((deUint32)0, subpassLayout));
2018 
2019 				const VkImageLayout			depthStencilLayout		(VK_IMAGE_LAYOUT_GENERAL);
2020 				const vector<Subpass>		subpasses				(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<deUint32>()));
2021 				vector<SubpassDependency>	deps;
2022 
2023 				// The first render pass lets the implementation add all subpass dependencies implicitly.
2024 				// On the following passes only the dependency from external to first subpass is defined as
2025 				// we need to make sure we have the image ready from previous render pass. In this case
2026 				// the dependency from subpass 0 to external is added implicitly by the implementation.
2027 				if (renderPassNdx > 0)
2028 				{
2029 					deps.push_back(SubpassDependency(VK_SUBPASS_EXTERNAL,										// deUint32				srcPass
2030 													 0,															// deUint32				dstPass
2031 													 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,				// VkPipelineStageFlags	srcStageMask
2032 													 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,						// VkPipelineStageFlags	dstStageMask
2033 													 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,						// VkAccessFlags		srcAccessMask
2034 													 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,	// VkAccessFlags		dstAccessMask
2035 													 0));														// VkDependencyFlags	flags
2036 				}
2037 
2038 				RenderPass					renderPass				(attachments, subpasses, deps);
2039 
2040 				renderPasses.push_back(renderPass);
2041 			}
2042 
2043 			const deUint32				blurKernel	(12u);
2044 			const ExternalTestConfig	testConfig	(VK_FORMAT_R8G8B8A8_UNORM, UVec2(128, 128), renderPasses, renderPassType, blurKernel);
2045 			const string				testName	("render_passes_" + de::toString(renderPassCounts[renderPassCountNdx]));
2046 
2047 			implicitGroup->addChild(new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
2048 		}
2049 
2050 		group->addChild(implicitGroup.release());
2051 	}
2052 
2053 	// Test late fragment operations using depth_stencil attachments in multipass rendering
2054 	{
2055 		const UVec2		renderSizes[]		=
2056 		{
2057 			UVec2(32, 32),
2058 			UVec2(64, 64),
2059 			UVec2(128, 128)
2060 		};
2061 
2062 		const deUint32	subpassCounts[]		= { 2u, 3u, 5u };
2063 
2064 		// Implementations must support at least one of the following formats
2065 		// for depth_stencil attachments
2066 		const VkFormat formats[]			=
2067 		{
2068 			VK_FORMAT_D24_UNORM_S8_UINT,
2069 			VK_FORMAT_D32_SFLOAT_S8_UINT
2070 		};
2071 
2072 		de::MovePtr<tcu::TestCaseGroup>	lateFragmentTestsGroup (new tcu::TestCaseGroup(testCtx, "late_fragment_tests", "wait for late fragment tests"));
2073 
2074 		for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
2075 		{
2076 			string							renderSizeGroupName	("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" + de::toString(renderSizes[renderSizeNdx].y()));
2077 			de::MovePtr<tcu::TestCaseGroup>	renderSizeGroup		(new tcu::TestCaseGroup(testCtx, renderSizeGroupName.c_str(), renderSizeGroupName.c_str()));
2078 
2079 			for (size_t subpassCountNdx = 0; subpassCountNdx < DE_LENGTH_OF_ARRAY(subpassCounts); subpassCountNdx++)
2080 			{
2081 				string							subpassGroupName	("subpass_count_" + de::toString(subpassCounts[subpassCountNdx]));
2082 				de::MovePtr<tcu::TestCaseGroup>	subpassCountGroup	(new tcu::TestCaseGroup(testCtx, subpassGroupName.c_str(), subpassGroupName.c_str()));
2083 
2084 				for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
2085 				{
2086 					const deUint32				subpassCount	(subpassCounts[subpassCountNdx]);
2087 					const deUint32				attachmentCount	(subpassCount);
2088 					vector<Subpass>				subpasses;
2089 					vector<Attachment>			attachments;
2090 					vector<SubpassDependency>	deps;
2091 
2092 					// Attachments
2093 					for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
2094 					{
2095 						const VkFormat				format						(formats[formatNdx]);
2096 						const VkSampleCountFlagBits	sampleCount					(VK_SAMPLE_COUNT_1_BIT);
2097 						const VkAttachmentLoadOp	loadOp						(VK_ATTACHMENT_LOAD_OP_CLEAR);
2098 						const VkAttachmentStoreOp	storeOp						((attachmentNdx == attachmentCount - 1)
2099 																					? VK_ATTACHMENT_STORE_OP_STORE
2100 																					: VK_ATTACHMENT_STORE_OP_DONT_CARE);
2101 						const VkAttachmentLoadOp	stencilLoadOp				(VK_ATTACHMENT_LOAD_OP_CLEAR);
2102 						const VkAttachmentStoreOp	stencilStoreOp				((attachmentNdx == attachmentCount - 1)
2103 																					? VK_ATTACHMENT_STORE_OP_STORE
2104 																					: VK_ATTACHMENT_STORE_OP_DONT_CARE);
2105 						const VkImageLayout			initialLayout				(VK_IMAGE_LAYOUT_UNDEFINED);
2106 						const VkImageLayout			finalLayout					(VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL);
2107 
2108 						attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalLayout));
2109 					}
2110 
2111 					// Subpasses
2112 					for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
2113 					{
2114 						vector<AttachmentReference>	inputAttachmentReferences;
2115 						const VkImageAspectFlags	inputAttachmentAspectMask	((renderPassType == RENDERPASS_TYPE_RENDERPASS2)
2116 																					? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_DEPTH_BIT)
2117 																					: static_cast<VkImageAspectFlags>(0));
2118 
2119 						// Input attachment references
2120 						if (subpassNdx > 0)
2121 							inputAttachmentReferences.push_back(AttachmentReference((deUint32)subpassNdx - 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, inputAttachmentAspectMask));
2122 
2123 						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>()));
2124 
2125 						// Subpass dependencies from current subpass to previous subpass.
2126 						// Subpasses will wait for the late fragment operations before reading the contents
2127 						// of previous subpass.
2128 						if (subpassNdx > 0)
2129 						{
2130 							deps.push_back(SubpassDependency((deUint32)subpassNdx - 1,							// deUint32				srcPass
2131 															 (deUint32)subpassNdx,								// deUint32				dstPass
2132 															 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,			// VkPipelineStageFlags	srcStageMask
2133 															 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
2134 																| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,	// VkPipelineStageFlags	dstStageMask
2135 															 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags		srcAccessMask
2136 															 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,				// VkAccessFlags		dstAccessMask
2137 															 VK_DEPENDENCY_BY_REGION_BIT));						// VkDependencyFlags	flags
2138 						}
2139 					}
2140 
2141 					const RenderPass		renderPass	(attachments, subpasses, deps);
2142 					const SubpassTestConfig	testConfig	(formats[formatNdx], renderSizes[renderSizeNdx], renderPass, renderPassType);
2143 					const string			format		(formatToName(formats[formatNdx]).c_str());
2144 
2145 					subpassCountGroup->addChild(new InstanceFactory1<SubpassDependencyTestInstance, SubpassTestConfig, SubpassPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, format, format, testConfig));
2146 				}
2147 
2148 				renderSizeGroup->addChild(subpassCountGroup.release());
2149 			}
2150 
2151 			lateFragmentTestsGroup->addChild(renderSizeGroup.release());
2152 		}
2153 
2154 		group->addChild(lateFragmentTestsGroup.release());
2155 	}
2156 }
2157 } // anonymous
2158 
createRenderPassSubpassDependencyTests(tcu::TestContext & testCtx)2159 tcu::TestCaseGroup* createRenderPassSubpassDependencyTests (tcu::TestContext& testCtx)
2160 {
2161 	return createTestGroup(testCtx, "subpass_dependencies", "Subpass dependency tests", initTests, RENDERPASS_TYPE_LEGACY);
2162 }
2163 
createRenderPass2SubpassDependencyTests(tcu::TestContext & testCtx)2164 tcu::TestCaseGroup* createRenderPass2SubpassDependencyTests (tcu::TestContext& testCtx)
2165 {
2166 	return createTestGroup(testCtx, "subpass_dependencies", "Subpass dependency tests", initTests, RENDERPASS_TYPE_RENDERPASS2);
2167 }
2168 } // vkt
2169