1/*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2019 The Khronos Group Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Tests fragment density map extension ( VK_EXT_fragment_density_map )
22 *//*--------------------------------------------------------------------*/
23
24#include "vktRenderPassFragmentDensityMapTests.hpp"
25#include "pipeline/vktPipelineImageUtil.hpp"
26#include "deMath.h"
27#include "vktTestCase.hpp"
28#include "vktTestGroupUtil.hpp"
29#include "vktCustomInstancesDevices.hpp"
30#include "vktRenderPassTestsUtil.hpp"
31#include "vkImageUtil.hpp"
32#include "vkQueryUtil.hpp"
33#include "vkCmdUtil.hpp"
34#include "vkRefUtil.hpp"
35#include "vkObjUtil.hpp"
36#include "vkBarrierUtil.hpp"
37#include "vkBuilderUtil.hpp"
38#include "tcuCommandLine.hpp"
39#include "tcuStringTemplate.hpp"
40#include "tcuTextureUtil.hpp"
41#include "tcuTestLog.hpp"
42#include <sstream>
43#include <vector>
44#include <set>
45
46// Each test generates an image with a color gradient where all colors should be unique when rendered without density map
47// ( and for multi_view tests - the quantity of each color in a histogram should be 2 instead of 1 ).
48// The whole density map has the same values defined by input fragment area ( one of the test input parameters ).
49// With density map enabled - the number of each color in a histogram should be [ fragmentArea.x * fragmentArea.y ]
50// ( that value will be doubled for multi_view case ).
51//
52// Additionally test checks if gl_FragSizeEXT shader variable has proper value ( as defined by fragmentArea input parameter ).
53//
54// Test variations:
55// - multi_view tests check if density map also works when VK_KHR_multiview extension is in use
56// - render_copy tests check if it's possible to copy results using input attachment descriptor ( this simulates deferred rendering behaviour )
57// - non_divisible_density_size tests check if subsampled images work when its dimension is not divisible by minFragmentDensityTexelSize
58// - N_samples tests check if multisampling works with VK_EXT_fragment_density_map extension
59// - static_* tests use density map loaded from CPU during vkCmdBeginRenderPass.
60// - dynamic_* tests use density map rendered on a GPU in a separate render pass
61// - deffered_* tests use density map loaded from CPU during VkEndCommandBuffer.
62// - *_nonsubsampled tests check if it's possible to use nonsubsampled images instead of subsampled ones
63
64// There are 3 render passes performed during most of the tests:
65//  - render pass that produces density map ( this rp is skipped when density map is static )
66//  - render pass that produces subsampled image using density map and eventually copies results to different image ( render_copy )
67//  - render pass that copies subsampled image to traditional image using sampler with VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT flag.
68//    ( because subsampled images cannot be retrieved to CPU in any other way ).
69// There are few tests that use additional subpass that resamples subsampled image using diferent density map.
70
71// Code of FragmentDensityMapTestInstance is also used to test subsampledLoads, subsampledCoarseReconstructionEarlyAccess,
72// maxDescriptorSetSubsampledSamplers properties.
73
74namespace vkt
75{
76
77namespace renderpass
78{
79
80using namespace vk;
81
82namespace
83{
84
85struct TestParams
86{
87	bool					dynamicDensityMap;
88	bool					deferredDensityMap;
89	bool					nonSubsampledImages;
90	bool					subsampledLoads;
91	bool					coarseReconstruction;
92	bool					imagelessFramebuffer;
93	bool					useMemoryAccess;
94	bool					useMaintenance5;
95	deUint32				samplersCount;
96	deUint32				viewCount;
97	bool					multiViewport;
98	bool					makeCopy;
99	float					renderMultiplier;
100	VkSampleCountFlagBits	colorSamples;
101	tcu::UVec2				fragmentArea;
102	tcu::UVec2				densityMapSize;
103	VkFormat				densityMapFormat;
104	const SharedGroupParams	groupParams;
105};
106
107struct Vertex4RGBA
108{
109	tcu::Vec4	position;
110	tcu::Vec4	uv;
111	tcu::Vec4	color;
112};
113
114de::SharedPtr<Move<vk::VkDevice>>	g_singletonDevice;
115
116VkDevice getDevice(Context& context)
117{
118	if (!g_singletonDevice)
119	{
120		const float queuePriority = 1.0f;
121
122		// Create a universal queue that supports graphics and compute
123		const VkDeviceQueueCreateInfo queueParams
124		{
125			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	// VkStructureType				sType;
126			DE_NULL,									// const void*					pNext;
127			0u,											// VkDeviceQueueCreateFlags		flags;
128			context.getUniversalQueueFamilyIndex(),		// deUint32						queueFamilyIndex;
129			1u,											// deUint32						queueCount;
130			&queuePriority								// const float*					pQueuePriorities;
131		};
132
133		// \note Extensions in core are not explicitly enabled even though
134		//		 they are in the extension list advertised to tests.
135		const auto& extensionPtrs = context.getDeviceCreationExtensions();
136
137		VkPhysicalDevicePortabilitySubsetFeaturesKHR	portabilitySubsetFeatures		= initVulkanStructure();
138		VkPhysicalDeviceMultiviewFeatures				multiviewFeatures				= initVulkanStructure();
139		VkPhysicalDeviceImagelessFramebufferFeatures	imagelessFramebufferFeatures	= initVulkanStructure();
140		VkPhysicalDeviceDynamicRenderingFeatures		dynamicRenderingFeatures		= initVulkanStructure();
141		VkPhysicalDeviceFragmentDensityMap2FeaturesEXT	fragmentDensityMap2Features		= initVulkanStructure();
142		VkPhysicalDeviceFragmentDensityMapFeaturesEXT	fragmentDensityMapFeatures		= initVulkanStructure();
143		VkPhysicalDeviceFeatures2						features2						= initVulkanStructure();
144
145		const auto addFeatures = makeStructChainAdder(&features2);
146
147		if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset"))
148			addFeatures(&portabilitySubsetFeatures);
149
150		if (context.isDeviceFunctionalitySupported("VK_KHR_multiview"))
151			addFeatures(&multiviewFeatures);
152
153		if (context.isDeviceFunctionalitySupported("VK_KHR_imageless_framebuffer"))
154			addFeatures(&imagelessFramebufferFeatures);
155
156		if (context.isDeviceFunctionalitySupported("VK_KHR_dynamic_rendering"))
157			addFeatures(&dynamicRenderingFeatures);
158
159		if (context.isDeviceFunctionalitySupported("VK_EXT_fragment_density_map2"))
160			addFeatures(&fragmentDensityMap2Features);
161
162		addFeatures(&fragmentDensityMapFeatures);
163
164		context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
165		features2.features.robustBufferAccess = VK_FALSE;
166
167		const VkDeviceCreateInfo deviceCreateInfo
168		{
169			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,							//sType;
170			&features2,														//pNext;
171			0u,																//flags
172			1,																//queueRecordCount;
173			&queueParams,													//pRequestedQueues;
174			0u,																//layerCount;
175			nullptr,														//ppEnabledLayerNames;
176			de::sizeU32(extensionPtrs),										// deUint32				enabledExtensionCount;
177			de::dataOrNull(extensionPtrs),									// const char* const*	ppEnabledExtensionNames;
178			nullptr,														//pEnabledFeatures;
179		};
180
181		Move<VkDevice> device = createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), context.getInstance(), context.getInstanceInterface(), context.getPhysicalDevice(), &deviceCreateInfo);
182		g_singletonDevice = de::SharedPtr<Move<VkDevice>>(new Move<VkDevice>(device));
183	}
184
185	return g_singletonDevice->get();
186}
187
188std::vector<Vertex4RGBA> createFullscreenMesh(deUint32 viewCount, tcu::Vec2 redGradient, tcu::Vec2 greenGradient)
189{
190	DE_ASSERT(viewCount > 0);
191
192	const auto&		r		= redGradient;
193	const auto&		g		= greenGradient;
194	const float		step	= 2.0f / static_cast<float>(viewCount);
195	float			xStart	= -1.0f;
196
197	std::vector<Vertex4RGBA> resultMesh;
198	for (deUint32 viewIndex = 0; viewIndex < viewCount ; ++viewIndex)
199	{
200		const float		fIndex		= static_cast<float>(viewIndex);
201		const deUint32	nextIndex	= viewIndex + 1;
202		const float		xEnd		= (nextIndex == viewCount) ? 1.0f : (-1.0f + step * static_cast<float>(nextIndex));
203
204		// quad vertex							position						uv								color
205		const Vertex4RGBA lowerLeftVertex	= { { xStart,  1.0f, 0.0f, 1.0f },	{ 0.0f, 1.0f, fIndex, 1.0f },	{ r.x(), g.y(), 0.0f, 1.0f } };
206		const Vertex4RGBA upperLeftVertex	= { { xStart, -1.0f, 0.0f, 1.0f },	{ 0.0f, 0.0f, fIndex, 1.0f },	{ r.x(), g.x(), 0.0f, 1.0f } };
207		const Vertex4RGBA lowerRightVertex	= { {   xEnd,  1.0f, 0.0f, 1.0f },	{ 1.0f, 1.0f, fIndex, 1.0f },	{ r.y(), g.y(), 0.0f, 1.0f } };
208		const Vertex4RGBA upperRightVertex	= { {   xEnd, -1.0f, 0.0f, 1.0f },	{ 1.0f, 0.0f, fIndex, 1.0f },	{ r.y(), g.x(), 0.0f, 1.0f } };
209
210		const std::vector<Vertex4RGBA> viewData
211		{
212			lowerLeftVertex, lowerRightVertex, upperLeftVertex,
213			upperLeftVertex, lowerRightVertex, upperRightVertex
214		};
215
216		resultMesh.insert(resultMesh.end(), viewData.begin(), viewData.end());
217		xStart = xEnd;
218	}
219
220	return resultMesh;
221}
222
223template <typename T>
224void createVertexBuffer(const DeviceInterface&		vk,
225						VkDevice					vkDevice,
226						const deUint32&				queueFamilyIndex,
227						SimpleAllocator&			memAlloc,
228						const std::vector<T>&		vertices,
229						Move<VkBuffer>&				vertexBuffer,
230						de::MovePtr<Allocation>&	vertexAlloc)
231{
232	const VkBufferCreateInfo vertexBufferParams =
233	{
234		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,			// VkStructureType		sType;
235		DE_NULL,										// const void*			pNext;
236		0u,												// VkBufferCreateFlags	flags;
237		(VkDeviceSize)(sizeof(T) * vertices.size()),	// VkDeviceSize			size;
238		VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,				// VkBufferUsageFlags	usage;
239		VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode		sharingMode;
240		1u,												// deUint32				queueFamilyIndexCount;
241		&queueFamilyIndex								// const deUint32*		pQueueFamilyIndices;
242	};
243
244	vertexBuffer	= createBuffer(vk, vkDevice, &vertexBufferParams);
245	vertexAlloc		= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
246	VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexAlloc->getMemory(), vertexAlloc->getOffset()));
247
248	// Upload vertex data
249	deMemcpy(vertexAlloc->getHostPtr(), vertices.data(), vertices.size() * sizeof(T));
250	flushAlloc(vk, vkDevice, *vertexAlloc);
251}
252
253void prepareImageAndImageView	(const DeviceInterface&			vk,
254								 VkDevice						vkDevice,
255								 SimpleAllocator&				memAlloc,
256								 VkImageCreateFlags				imageCreateFlags,
257								 VkFormat						format,
258								 VkExtent3D						extent,
259								 deUint32						arrayLayers,
260								 VkSampleCountFlagBits			samples,
261								 VkImageUsageFlags				usage,
262								 deUint32						queueFamilyIndex,
263								 VkImageViewCreateFlags			viewFlags,
264								 VkImageViewType				viewType,
265								 const VkComponentMapping&		channels,
266								 const VkImageSubresourceRange&	subresourceRange,
267								 Move<VkImage>&					image,
268								 de::MovePtr<Allocation>&		imageAlloc,
269								 Move<VkImageView>&				imageView)
270{
271	const VkImageCreateInfo imageCreateInfo
272	{
273		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType			sType;
274		DE_NULL,									// const void*				pNext;
275		imageCreateFlags,							// VkImageCreateFlags		flags;
276		VK_IMAGE_TYPE_2D,							// VkImageType				imageType;
277		format,										// VkFormat					format;
278		extent,										// VkExtent3D				extent;
279		1u,											// deUint32					mipLevels;
280		arrayLayers,								// deUint32					arrayLayers;
281		samples,									// VkSampleCountFlagBits	samples;
282		VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling			tiling;
283		usage,										// VkImageUsageFlags		usage;
284		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode			sharingMode;
285		1u,											// deUint32					queueFamilyIndexCount;
286		&queueFamilyIndex,							// const deUint32*			pQueueFamilyIndices;
287		VK_IMAGE_LAYOUT_UNDEFINED					// VkImageLayout			initialLayout;
288	};
289
290	image = createImage(vk, vkDevice, &imageCreateInfo);
291
292	// Allocate and bind color image memory
293	imageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any);
294	VK_CHECK(vk.bindImageMemory(vkDevice, *image, imageAlloc->getMemory(), imageAlloc->getOffset()));
295
296	// create image view for subsampled image
297	const VkImageViewCreateInfo imageViewCreateInfo =
298	{
299		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType;
300		DE_NULL,									// const void*				pNext;
301		viewFlags,									// VkImageViewCreateFlags	flags;
302		*image,										// VkImage					image;
303		viewType,									// VkImageViewType			viewType;
304		format,										// VkFormat					format;
305		channels,									// VkChannelMapping			channels;
306		subresourceRange							// VkImageSubresourceRange	subresourceRange;
307	};
308
309	imageView = createImageView(vk, vkDevice, &imageViewCreateInfo);
310}
311
312// Class that provides abstraction over renderpass and renderpass2.
313class RenderPassWrapperBase
314{
315public:
316
317	RenderPassWrapperBase() = default;
318	virtual ~RenderPassWrapperBase() = default;
319
320	virtual Move<VkRenderPass>	createRenderPassProduceDynamicDensityMap	(deUint32						viewMask) const = 0;
321	virtual Move<VkRenderPass>	createRenderPassProduceSubsampledImage		(deUint32						viewMask,
322																			 bool							makeCopySubpass,
323																			 bool							resampleSubsampled) const = 0;
324	virtual Move<VkRenderPass>	createRenderPassOutputSubsampledImage		() const = 0;
325
326	virtual void				cmdBeginRenderPass							(VkCommandBuffer				cmdBuffer,
327																			 const VkRenderPassBeginInfo*	pRenderPassBegin) const = 0;
328	virtual void				cmdNextSubpass								(VkCommandBuffer				cmdBuffer) const = 0;
329	virtual void				cmdEndRenderPass							(VkCommandBuffer				cmdBuffer) const = 0;
330};
331
332// Helper template that lets us define all used types basing on single enum value.
333template <RenderingType>
334struct RenderPassTraits;
335
336template <> struct RenderPassTraits<RENDERING_TYPE_RENDERPASS_LEGACY>
337{
338	typedef AttachmentDescription1	AttachmentDesc;
339	typedef AttachmentReference1	AttachmentRef;
340	typedef SubpassDescription1		SubpassDesc;
341	typedef SubpassDependency1		SubpassDep;
342	typedef RenderPassCreateInfo1	RenderPassCreateInfo;
343	typedef RenderpassSubpass1		RenderpassSubpass;
344};
345
346template <> struct RenderPassTraits<RENDERING_TYPE_RENDERPASS2>
347{
348	typedef AttachmentDescription2	AttachmentDesc;
349	typedef AttachmentReference2	AttachmentRef;
350	typedef SubpassDescription2		SubpassDesc;
351	typedef SubpassDependency2		SubpassDep;
352	typedef RenderPassCreateInfo2	RenderPassCreateInfo;
353	typedef RenderpassSubpass2		RenderpassSubpass;
354};
355
356// Template that can be used to construct required
357// renderpasses using legacy renderpass and renderpass2.
358template <RenderingType RenderingTypeValue>
359class RenderPassWrapper: public RenderPassWrapperBase
360{
361	typedef typename RenderPassTraits<RenderingTypeValue>::AttachmentDesc		AttachmentDesc;
362	typedef typename RenderPassTraits<RenderingTypeValue>::AttachmentRef		AttachmentRef;
363	typedef typename RenderPassTraits<RenderingTypeValue>::SubpassDesc			SubpassDesc;
364	typedef typename RenderPassTraits<RenderingTypeValue>::SubpassDep			SubpassDep;
365	typedef typename RenderPassTraits<RenderingTypeValue>::RenderPassCreateInfo	RenderPassCreateInfo;
366	typedef typename RenderPassTraits<RenderingTypeValue>::RenderpassSubpass	RenderpassSubpass;
367
368public:
369
370	RenderPassWrapper(const DeviceInterface& vk, const VkDevice vkDevice, const TestParams& testParams);
371	~RenderPassWrapper() = default;
372
373	Move<VkRenderPass>	createRenderPassProduceDynamicDensityMap	(deUint32						viewMask) const override;
374	Move<VkRenderPass>	createRenderPassProduceSubsampledImage		(deUint32						viewMask,
375																	 bool							makeCopySubpass,
376																	 bool							resampleSubsampled) const override;
377	Move<VkRenderPass>	createRenderPassOutputSubsampledImage		() const override;
378
379	void				cmdBeginRenderPass							(VkCommandBuffer				cmdBufferm,
380																	 const VkRenderPassBeginInfo*	pRenderPassBegin) const override;
381	void				cmdNextSubpass								(VkCommandBuffer				cmdBuffer) const override;
382	void				cmdEndRenderPass							(VkCommandBuffer				cmdBuffer) const override;
383
384private:
385
386	const DeviceInterface&	m_vk;
387	const VkDevice			m_vkDevice;
388	const TestParams&		m_testParams;
389
390	const typename RenderpassSubpass::SubpassBeginInfo	m_subpassBeginInfo;
391	const typename RenderpassSubpass::SubpassEndInfo	m_subpassEndInfo;
392};
393
394template<RenderingType RenderingTypeValue>
395RenderPassWrapper<RenderingTypeValue>::RenderPassWrapper(const DeviceInterface& vk, const VkDevice vkDevice, const TestParams& testParams)
396	: RenderPassWrapperBase		()
397	, m_vk						(vk)
398	, m_vkDevice				(vkDevice)
399	, m_testParams				(testParams)
400	, m_subpassBeginInfo		(DE_NULL, testParams.groupParams->useSecondaryCmdBuffer ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE)
401	, m_subpassEndInfo			(DE_NULL)
402{
403}
404
405template<RenderingType RenderingTypeValue>
406Move<VkRenderPass> RenderPassWrapper<RenderingTypeValue>::createRenderPassProduceDynamicDensityMap(deUint32 viewMask) const
407{
408	DE_ASSERT(m_testParams.dynamicDensityMap);
409
410	std::vector<AttachmentDesc> attachmentDescriptions
411	{
412		{
413			DE_NULL,															// const void*						pNext
414			(VkAttachmentDescriptionFlags)0,									// VkAttachmentDescriptionFlags		flags
415			m_testParams.densityMapFormat,										// VkFormat							format
416			VK_SAMPLE_COUNT_1_BIT,												// VkSampleCountFlagBits			samples
417			VK_ATTACHMENT_LOAD_OP_CLEAR,										// VkAttachmentLoadOp				loadOp
418			VK_ATTACHMENT_STORE_OP_STORE,										// VkAttachmentStoreOp				storeOp
419			VK_ATTACHMENT_LOAD_OP_DONT_CARE,									// VkAttachmentLoadOp				stencilLoadOp
420			VK_ATTACHMENT_STORE_OP_DONT_CARE,									// VkAttachmentStoreOp				stencilStoreOp
421			VK_IMAGE_LAYOUT_UNDEFINED,											// VkImageLayout					initialLayout
422			VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT					// VkImageLayout					finalLayout
423		}
424	};
425
426	std::vector<AttachmentRef> colorAttachmentRefs
427	{
428		{ DE_NULL, 0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT }
429	};
430
431	std::vector<SubpassDesc> subpassDescriptions
432	{
433		{
434			DE_NULL,
435			(VkSubpassDescriptionFlags)0,										// VkSubpassDescriptionFlags		flags
436			VK_PIPELINE_BIND_POINT_GRAPHICS,									// VkPipelineBindPoint				pipelineBindPoint
437			viewMask,															// deUint32							viewMask
438			0u,																	// deUint32							inputAttachmentCount
439			DE_NULL,															// const VkAttachmentReference*		pInputAttachments
440			static_cast<deUint32>(colorAttachmentRefs.size()),					// deUint32							colorAttachmentCount
441			colorAttachmentRefs.data(),											// const VkAttachmentReference*		pColorAttachments
442			DE_NULL,															// const VkAttachmentReference*		pResolveAttachments
443			DE_NULL,															// const VkAttachmentReference*		pDepthStencilAttachment
444			0u,																	// deUint32							preserveAttachmentCount
445			DE_NULL																// const deUint32*					pPreserveAttachments
446		}
447	};
448
449	std::vector<SubpassDep> subpassDependencies
450	{
451		{
452			DE_NULL,															// const void*				pNext
453			0u,																	// uint32_t					srcSubpass
454			VK_SUBPASS_EXTERNAL,												// uint32_t					dstSubpass
455			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,						// VkPipelineStageFlags		srcStageMask
456			VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT,					// VkPipelineStageFlags		dstStageMask
457			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,								// VkAccessFlags			srcAccessMask
458			VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT,						// VkAccessFlags			dstAccessMask
459			VK_DEPENDENCY_BY_REGION_BIT,										// VkDependencyFlags		dependencyFlags
460			0u																	// deInt32					viewOffset
461		}
462	};
463
464	const RenderPassCreateInfo renderPassInfo(
465		DE_NULL,																// const void*						pNext
466		(VkRenderPassCreateFlags)0,												// VkRenderPassCreateFlags			flags
467		static_cast<deUint32>(attachmentDescriptions.size()),					// deUint32							attachmentCount
468		attachmentDescriptions.data(),											// const VkAttachmentDescription*	pAttachments
469		static_cast<deUint32>(subpassDescriptions.size()),						// deUint32							subpassCount
470		subpassDescriptions.data(),												// const VkSubpassDescription*		pSubpasses
471		static_cast<deUint32>(subpassDependencies.size()),						// deUint32							dependencyCount
472		subpassDependencies.empty() ? DE_NULL : subpassDependencies.data(),		// const VkSubpassDependency*		pDependencies
473		0u,																		// deUint32							correlatedViewMaskCount
474		DE_NULL																	// const deUint32*					pCorrelatedViewMasks
475	);
476
477	return renderPassInfo.createRenderPass(m_vk, m_vkDevice);
478}
479
480template<RenderingType RenderingTypeValue>
481Move<VkRenderPass> RenderPassWrapper<RenderingTypeValue>::createRenderPassProduceSubsampledImage(deUint32	viewMask,
482																								 bool		makeCopySubpass,
483																								 bool		resampleSubsampled) const
484{
485	const void* constNullPtr				= DE_NULL;
486	deUint32	multisampleAttachmentIndex	= 0;
487	deUint32	copyAttachmentIndex			= 0;
488	deUint32	densityMapAttachmentIndex	= 0;
489
490	// add color image
491	VkAttachmentLoadOp			loadOp = resampleSubsampled ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR;
492	std::vector<AttachmentDesc> attachmentDescriptions
493	{
494		// Output color attachment
495		{
496			DE_NULL,															// const void*						pNext
497			(VkAttachmentDescriptionFlags)0,									// VkAttachmentDescriptionFlags		flags
498			VK_FORMAT_R8G8B8A8_UNORM,											// VkFormat							format
499			m_testParams.colorSamples,											// VkSampleCountFlagBits			samples
500			loadOp,																// VkAttachmentLoadOp				loadOp
501			VK_ATTACHMENT_STORE_OP_STORE,										// VkAttachmentStoreOp				storeOp
502			VK_ATTACHMENT_LOAD_OP_DONT_CARE,									// VkAttachmentLoadOp				stencilLoadOp
503			VK_ATTACHMENT_STORE_OP_DONT_CARE,									// VkAttachmentStoreOp				stencilStoreOp
504			VK_IMAGE_LAYOUT_UNDEFINED,											// VkImageLayout					initialLayout
505			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL							// VkImageLayout					finalLayout
506		}
507	};
508
509	// add resolve image when we use more than one sample per fragment
510	if (m_testParams.colorSamples != VK_SAMPLE_COUNT_1_BIT)
511	{
512		multisampleAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
513		attachmentDescriptions.emplace_back(
514			constNullPtr,														// const void*						pNext
515			(VkAttachmentDescriptionFlags)0,									// VkAttachmentDescriptionFlags		flags
516			VK_FORMAT_R8G8B8A8_UNORM,											// VkFormat							format
517			VK_SAMPLE_COUNT_1_BIT,												// VkSampleCountFlagBits			samples
518			VK_ATTACHMENT_LOAD_OP_CLEAR,										// VkAttachmentLoadOp				loadOp
519			VK_ATTACHMENT_STORE_OP_STORE,										// VkAttachmentStoreOp				storeOp
520			VK_ATTACHMENT_LOAD_OP_DONT_CARE,									// VkAttachmentLoadOp				stencilLoadOp
521			VK_ATTACHMENT_STORE_OP_DONT_CARE,									// VkAttachmentStoreOp				stencilStoreOp
522			VK_IMAGE_LAYOUT_UNDEFINED,											// VkImageLayout					initialLayout
523			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL							// VkImageLayout					finalLayout
524		);
525	}
526
527	// add color image copy ( when render_copy is used )
528	if (makeCopySubpass)
529	{
530		copyAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
531		attachmentDescriptions.emplace_back(
532			constNullPtr,														// const void*						pNext
533			(VkAttachmentDescriptionFlags)0,									// VkAttachmentDescriptionFlags		flags
534			VK_FORMAT_R8G8B8A8_UNORM,											// VkFormat							format
535			m_testParams.colorSamples,											// VkSampleCountFlagBits			samples
536			VK_ATTACHMENT_LOAD_OP_CLEAR,										// VkAttachmentLoadOp				loadOp
537			VK_ATTACHMENT_STORE_OP_STORE,										// VkAttachmentStoreOp				storeOp
538			VK_ATTACHMENT_LOAD_OP_DONT_CARE,									// VkAttachmentLoadOp				stencilLoadOp
539			VK_ATTACHMENT_STORE_OP_DONT_CARE,									// VkAttachmentStoreOp				stencilStoreOp
540			VK_IMAGE_LAYOUT_UNDEFINED,											// VkImageLayout					initialLayout
541			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL							// VkImageLayout					finalLayout
542		);
543	}
544
545	// add density map
546	densityMapAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
547	attachmentDescriptions.emplace_back(
548		constNullPtr,															// const void*						pNext
549		(VkAttachmentDescriptionFlags)0,										// VkAttachmentDescriptionFlags		flags
550		m_testParams.densityMapFormat,											// VkFormat							format
551		VK_SAMPLE_COUNT_1_BIT,													// VkSampleCountFlagBits			samples
552		VK_ATTACHMENT_LOAD_OP_LOAD,												// VkAttachmentLoadOp				loadOp
553		VK_ATTACHMENT_STORE_OP_DONT_CARE,										// VkAttachmentStoreOp				storeOp
554		VK_ATTACHMENT_LOAD_OP_DONT_CARE,										// VkAttachmentLoadOp				stencilLoadOp
555		VK_ATTACHMENT_STORE_OP_DONT_CARE,										// VkAttachmentStoreOp				stencilStoreOp
556		VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT,						// VkImageLayout					initialLayout
557		VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT						// VkImageLayout					finalLayout
558	);
559
560	std::vector<AttachmentRef> colorAttachmentRefs0
561	{
562		{ DE_NULL, 0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT }
563	};
564
565	// for multisampled scenario we need to add resolve attachment
566	// (for makeCopy scenario it is used in second subpass)
567	AttachmentRef*	pResolveAttachments		= DE_NULL;
568	AttachmentRef	resolveAttachmentRef
569	{
570		DE_NULL,
571		multisampleAttachmentIndex,
572		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
573		VK_IMAGE_ASPECT_COLOR_BIT
574	};
575	if (m_testParams.colorSamples != VK_SAMPLE_COUNT_1_BIT)
576		pResolveAttachments = &resolveAttachmentRef;
577
578	std::vector<SubpassDesc> subpassDescriptions
579	{
580		{
581			DE_NULL,
582			(VkSubpassDescriptionFlags)0,							// VkSubpassDescriptionFlags	flags
583			VK_PIPELINE_BIND_POINT_GRAPHICS,						// VkPipelineBindPoint			pipelineBindPoint
584			viewMask,												// deUint32						viewMask
585			0u,														// deUint32						inputAttachmentCount
586			DE_NULL,												// const VkAttachmentReference*	pInputAttachments
587			static_cast<deUint32>(colorAttachmentRefs0.size()),		// deUint32						colorAttachmentCount
588			colorAttachmentRefs0.data(),							// const VkAttachmentReference*	pColorAttachments
589			makeCopySubpass ? DE_NULL : pResolveAttachments,		// const VkAttachmentReference*	pResolveAttachments
590			DE_NULL,												// const VkAttachmentReference*	pDepthStencilAttachment
591			0u,														// deUint32						preserveAttachmentCount
592			DE_NULL													// const deUint32*				pPreserveAttachments
593		}
594	};
595
596	std::vector<AttachmentRef>	inputAttachmentRefs1
597	{
598		{ DE_NULL, 0u, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT }
599	};
600	std::vector<AttachmentRef>	colorAttachmentRefs1
601	{
602		{ DE_NULL, copyAttachmentIndex, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT }
603	};
604	std::vector<SubpassDep>		subpassDependencies;
605
606	if (makeCopySubpass)
607	{
608		subpassDescriptions.push_back({
609			DE_NULL,
610			(VkSubpassDescriptionFlags)0,							// VkSubpassDescriptionFlags	flags
611			VK_PIPELINE_BIND_POINT_GRAPHICS,						// VkPipelineBindPoint			pipelineBindPoint
612			viewMask,												// deUint32						viewMask
613			static_cast<deUint32>(inputAttachmentRefs1.size()),		// deUint32						inputAttachmentCount
614			inputAttachmentRefs1.data(),							// const VkAttachmentReference*	pInputAttachments
615			static_cast<deUint32>(colorAttachmentRefs1.size()),		// deUint32						colorAttachmentCount
616			colorAttachmentRefs1.data(),							// const VkAttachmentReference*	pColorAttachments
617			pResolveAttachments,									// const VkAttachmentReference*	pResolveAttachments
618			DE_NULL,												// const VkAttachmentReference*	pDepthStencilAttachment
619			0u,														// deUint32						preserveAttachmentCount
620			DE_NULL													// const deUint32*				pPreserveAttachments
621		});
622
623		VkDependencyFlags dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
624		if (m_testParams.viewCount > 1)
625			dependencyFlags |= VK_DEPENDENCY_VIEW_LOCAL_BIT;
626
627		subpassDependencies.emplace_back(
628			constNullPtr,																// const void*				pNext
629			0u,																			// uint32_t					srcSubpass
630			1u,																			// uint32_t					dstSubpass
631			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,								// VkPipelineStageFlags		srcStageMask
632			VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,										// VkPipelineStageFlags		dstStageMask
633			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,										// VkAccessFlags			srcAccessMask
634			VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,										// VkAccessFlags			dstAccessMask
635			dependencyFlags,															// VkDependencyFlags		dependencyFlags
636			0u																			// deInt32					viewOffset
637		);
638	}
639
640	VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
641
642	// for coarse reconstruction we need to put barrier on vertex stage
643	if (m_testParams.coarseReconstruction)
644		dstStageMask = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT;
645
646	subpassDependencies.emplace_back(
647		constNullPtr,																	// const void*				pNext
648		static_cast<deUint32>(subpassDescriptions.size())-1u,							// uint32_t					srcSubpass
649		VK_SUBPASS_EXTERNAL,															// uint32_t					dstSubpass
650		VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,									// VkPipelineStageFlags		srcStageMask
651		dstStageMask,																	// VkPipelineStageFlags		dstStageMask
652		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,											// VkAccessFlags			srcAccessMask
653		VK_ACCESS_SHADER_READ_BIT,														// VkAccessFlags			dstAccessMask
654		VK_DEPENDENCY_BY_REGION_BIT,													// VkDependencyFlags		dependencyFlags
655		0u																				// deInt32					viewOffset
656	);
657
658	VkRenderPassFragmentDensityMapCreateInfoEXT renderPassFragmentDensityMap
659	{
660		VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT,
661		DE_NULL,
662		{ densityMapAttachmentIndex, VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT }
663	};
664
665	void* renderPassInfoPNext = (void*)&renderPassFragmentDensityMap;
666
667	const RenderPassCreateInfo	renderPassInfo(
668		renderPassInfoPNext,														// const void*						pNext
669		(VkRenderPassCreateFlags)0,													// VkRenderPassCreateFlags			flags
670		static_cast<deUint32>(attachmentDescriptions.size()),						// deUint32							attachmentCount
671		attachmentDescriptions.data(),												// const VkAttachmentDescription*	pAttachments
672		static_cast<deUint32>(subpassDescriptions.size()),							// deUint32							subpassCount
673		subpassDescriptions.data(),													// const VkSubpassDescription*		pSubpasses
674		static_cast<deUint32>(subpassDependencies.size()),							// deUint32							dependencyCount
675		subpassDependencies.data(),													// const VkSubpassDependency*		pDependencies
676		0u,																			// deUint32							correlatedViewMaskCount
677		DE_NULL																		// const deUint32*					pCorrelatedViewMasks
678	);
679
680	return renderPassInfo.createRenderPass(m_vk, m_vkDevice);
681}
682
683template<RenderingType RenderingTypeValue>
684Move<VkRenderPass> RenderPassWrapper<RenderingTypeValue>::createRenderPassOutputSubsampledImage() const
685{
686	// copy subsampled image to ordinary image - you cannot retrieve subsampled image to CPU in any way.
687	// You must first convert it into plain image through rendering
688	std::vector<AttachmentDesc> attachmentDescriptions
689	{
690		// output attachment
691		{
692			DE_NULL,											// const void*						pNext
693			(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags
694			VK_FORMAT_R8G8B8A8_UNORM,							// VkFormat							format
695			VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples
696			VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp
697			VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp
698			VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp
699			VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp
700			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout					initialLayout
701			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout
702		},
703	};
704
705	std::vector<AttachmentRef> colorAttachmentRefs
706	{
707		{ DE_NULL, 0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_COLOR_BIT }
708	};
709
710	std::vector<SubpassDesc> subpassDescriptions
711	{
712		{
713			DE_NULL,
714			(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags		flags
715			VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint
716			0u,													// deUint32							viewMask
717			0u,													// deUint32							inputAttachmentCount
718			DE_NULL,											// const VkAttachmentReference*		pInputAttachments
719			static_cast<deUint32>(colorAttachmentRefs.size()),	// deUint32							colorAttachmentCount
720			colorAttachmentRefs.data(),							// const VkAttachmentReference*		pColorAttachments
721			DE_NULL,											// const VkAttachmentReference*		pResolveAttachments
722			DE_NULL,											// const VkAttachmentReference*		pDepthStencilAttachment
723			0u,													// deUint32							preserveAttachmentCount
724			DE_NULL												// const deUint32*					pPreserveAttachments
725		}
726	};
727
728	const RenderPassCreateInfo	renderPassInfo(
729		DE_NULL,												// const void*						pNext
730		(VkRenderPassCreateFlags)0,								// VkRenderPassCreateFlags			flags
731		static_cast<deUint32>(attachmentDescriptions.size()),	// deUint32							attachmentCount
732		attachmentDescriptions.data(),							// const VkAttachmentDescription*	pAttachments
733		static_cast<deUint32>(subpassDescriptions.size()),		// deUint32							subpassCount
734		subpassDescriptions.data(),								// const VkSubpassDescription*		pSubpasses
735		0,														// deUint32							dependencyCount
736		DE_NULL,												// const VkSubpassDependency*		pDependencies
737		0u,														// deUint32							correlatedViewMaskCount
738		DE_NULL													// const deUint32*					pCorrelatedViewMasks
739	);
740
741	return renderPassInfo.createRenderPass(m_vk, m_vkDevice);
742}
743
744template<RenderingType RenderingTypeValue>
745void RenderPassWrapper<RenderingTypeValue>::cmdBeginRenderPass(VkCommandBuffer cmdBuffer, const VkRenderPassBeginInfo* pRenderPassBegin) const
746{
747	RenderpassSubpass::cmdBeginRenderPass(m_vk, cmdBuffer, pRenderPassBegin, &m_subpassBeginInfo);
748}
749
750template<RenderingType RenderingTypeValue>
751void RenderPassWrapper<RenderingTypeValue>::cmdNextSubpass(VkCommandBuffer cmdBuffer) const
752{
753	RenderpassSubpass::cmdNextSubpass(m_vk, cmdBuffer, &m_subpassBeginInfo, &m_subpassEndInfo);
754}
755
756template<RenderingType RenderingTypeValue>
757void RenderPassWrapper<RenderingTypeValue>::cmdEndRenderPass(VkCommandBuffer cmdBuffer) const
758{
759	RenderpassSubpass::cmdEndRenderPass(m_vk, cmdBuffer, &m_subpassEndInfo);
760}
761
762Move<VkFramebuffer> createImagelessFrameBuffer(const DeviceInterface& vk, VkDevice vkDevice, VkRenderPass renderPass, VkExtent3D size, const std::vector<VkFramebufferAttachmentImageInfo>& attachmentInfo)
763{
764	const deUint32 attachmentCount = static_cast<deUint32>(attachmentInfo.size());
765	const VkFramebufferAttachmentsCreateInfo framebufferAttachmentsCreateInfo
766	{
767		VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO,		// VkStructureType								sType;
768		DE_NULL,													// const void*									pNext;
769		attachmentCount,											// deUint32										attachmentImageInfoCount;
770		&attachmentInfo[0]											// const VkFramebufferAttachmentImageInfo*		pAttachmentImageInfos;
771	};
772
773	const VkFramebufferCreateInfo framebufferParams
774	{
775		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,					// VkStructureType			sType;
776		&framebufferAttachmentsCreateInfo,							// const void*				pNext;
777		VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT,						// VkFramebufferCreateFlags	flags;
778		renderPass,													// VkRenderPass				renderPass;
779		attachmentCount,											// deUint32					attachmentCount;
780		DE_NULL,													// const VkImageView*		pAttachments;
781		size.width,													// deUint32					width;
782		size.height,												// deUint32					height;
783		1u															// deUint32					layers;
784	};
785
786	return createFramebuffer(vk, vkDevice, &framebufferParams);
787}
788
789Move<VkFramebuffer> createFrameBuffer(const DeviceInterface& vk, VkDevice vkDevice, VkRenderPass renderPass, VkExtent3D size, const std::vector<VkImageView>& imageViews)
790{
791	return makeFramebuffer(vk, vkDevice, renderPass, static_cast<deUint32>(imageViews.size()), imageViews.data(), size.width, size.height);
792}
793
794void copyBufferToImage(const DeviceInterface&					vk,
795					   VkDevice									device,
796					   VkQueue									queue,
797					   deUint32									queueFamilyIndex,
798					   const VkBuffer&							buffer,
799					   VkDeviceSize								bufferSize,
800					   const VkExtent3D&						imageSize,
801					   deUint32									arrayLayers,
802					   VkImage									destImage)
803{
804	Move<VkCommandPool>		cmdPool					= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
805	Move<VkCommandBuffer>	cmdBuffer				= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
806	Move<VkFence>			fence					= createFence(vk, device);
807	VkImageLayout			destImageLayout			= VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT;
808	VkPipelineStageFlags	destImageDstStageFlags	= VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT;
809	VkAccessFlags			finalAccessMask			= VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT;
810
811	const VkCommandBufferBeginInfo cmdBufferBeginInfo =
812	{
813		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,		// VkStructureType					sType;
814		DE_NULL,											// const void*						pNext;
815		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,		// VkCommandBufferUsageFlags		flags;
816		(const VkCommandBufferInheritanceInfo*)DE_NULL,
817	};
818
819	const VkBufferImageCopy copyRegion =
820	{
821		0,													// VkDeviceSize					bufferOffset
822		0,													// deUint32						bufferRowLength
823		0,													// deUint32						bufferImageHeight
824		{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, arrayLayers },	// VkImageSubresourceLayers		imageSubresource
825		{ 0, 0, 0 },										// VkOffset3D					imageOffset
826		imageSize											// VkExtent3D					imageExtent
827	};
828
829	// Barriers for copying buffer to image
830	const VkBufferMemoryBarrier preBufferBarrier = makeBufferMemoryBarrier(
831		VK_ACCESS_HOST_WRITE_BIT,							// VkAccessFlags	srcAccessMask;
832		VK_ACCESS_TRANSFER_READ_BIT,						// VkAccessFlags	dstAccessMask;
833		buffer,												// VkBuffer			buffer;
834		0u,													// VkDeviceSize		offset;
835		bufferSize											// VkDeviceSize		size;
836	);
837
838	const VkImageSubresourceRange subresourceRange
839	{														// VkImageSubresourceRange	subresourceRange;
840		VK_IMAGE_ASPECT_COLOR_BIT,							// VkImageAspectFlags		aspect;
841		0u,													// deUint32					baseMipLevel;
842		1u,													// deUint32					mipLevels;
843		0u,													// deUint32					baseArraySlice;
844		arrayLayers											// deUint32					arraySize;
845	};
846
847	const VkImageMemoryBarrier preImageBarrier = makeImageMemoryBarrier(
848		0u,													// VkAccessFlags			srcAccessMask;
849		VK_ACCESS_TRANSFER_WRITE_BIT,						// VkAccessFlags			dstAccessMask;
850		VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout			oldLayout;
851		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout			newLayout;
852		destImage,											// VkImage					image;
853		subresourceRange									// VkImageSubresourceRange	subresourceRange;
854	);
855
856	const VkImageMemoryBarrier postImageBarrier = makeImageMemoryBarrier(
857		VK_ACCESS_TRANSFER_WRITE_BIT,						// VkAccessFlags			srcAccessMask;
858		finalAccessMask,									// VkAccessFlags			dstAccessMask;
859		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout			oldLayout;
860		destImageLayout,									// VkImageLayout			newLayout;
861		destImage,											// VkImage					image;
862		subresourceRange									// VkImageSubresourceRange	subresourceRange;
863	);
864
865	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
866	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
867	vk.cmdCopyBufferToImage(*cmdBuffer, buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
868	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, destImageDstStageFlags, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
869	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
870
871	const VkPipelineStageFlags pipelineStageFlags = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
872
873	const VkSubmitInfo submitInfo =
874	{
875		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType				sType;
876		DE_NULL,						// const void*					pNext;
877		0u,								// deUint32						waitSemaphoreCount;
878		DE_NULL,						// const VkSemaphore*			pWaitSemaphores;
879		&pipelineStageFlags,			// const VkPipelineStageFlags*	pWaitDstStageMask;
880		1u,								// deUint32						commandBufferCount;
881		&cmdBuffer.get(),				// const VkCommandBuffer*		pCommandBuffers;
882		0u,								// deUint32						signalSemaphoreCount;
883		DE_NULL							// const VkSemaphore*			pSignalSemaphores;
884	};
885
886	try
887	{
888		VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
889		VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull) /* infinity */));
890	}
891	catch (...)
892	{
893		VK_CHECK(vk.deviceWaitIdle(device));
894		throw;
895	}
896}
897
898Move<VkPipeline> buildGraphicsPipeline(const DeviceInterface&						vk,
899										const VkDevice								device,
900										const VkPipelineLayout						pipelineLayout,
901										const VkShaderModule						vertexShaderModule,
902										const VkShaderModule						fragmentShaderModule,
903										const VkRenderPass							renderPass,
904										const std::vector<VkViewport>&				viewportVect,
905										const std::vector<VkRect2D>&				scissorVect,
906										const deUint32								subpass,
907										const VkPipelineMultisampleStateCreateInfo*	multisampleStateCreateInfo,
908										const void*									pNext,
909										const bool									useDensityMapAttachment,
910										const bool									useMaintenance5 = false)
911{
912	std::vector<VkPipelineShaderStageCreateInfo> pipelineShaderStageParams(2,
913		{
914			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType
915			DE_NULL,												// const void*							pNext
916			0u,														// VkPipelineShaderStageCreateFlags		flags
917			VK_SHADER_STAGE_VERTEX_BIT,								// VkShaderStageFlagBits				stage
918			vertexShaderModule,										// VkShaderModule						module
919			"main",													// const char*							pName
920			DE_NULL													// const VkSpecializationInfo*			pSpecializationInfo
921		});
922	pipelineShaderStageParams[1].stage	= VK_SHADER_STAGE_FRAGMENT_BIT;
923	pipelineShaderStageParams[1].module	= fragmentShaderModule;
924
925	const VkVertexInputBindingDescription vertexInputBindingDescription
926	{
927		0u,																// deUint32					binding;
928		sizeof(Vertex4RGBA),											// deUint32					strideInBytes;
929		VK_VERTEX_INPUT_RATE_VERTEX										// VkVertexInputStepRate	inputRate;
930	};
931
932	std::vector<VkVertexInputAttributeDescription> vertexInputAttributeDescriptions
933	{
934		{ 0u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, 0u },
935		{ 1u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, (deUint32)(sizeof(float) * 4) },
936		{ 2u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, (deUint32)(sizeof(float) * 8) }
937	};
938
939	const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo
940	{
941		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
942		DE_NULL,														// const void*								pNext;
943		0u,																// VkPipelineVertexInputStateCreateFlags	flags;
944		1u,																// deUint32									vertexBindingDescriptionCount;
945		&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
946		static_cast<deUint32>(vertexInputAttributeDescriptions.size()),	// deUint32									vertexAttributeDescriptionCount;
947		vertexInputAttributeDescriptions.data()							// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
948	};
949
950	const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo
951	{
952		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType
953		DE_NULL,														// const void*								pNext
954		0u,																// VkPipelineInputAssemblyStateCreateFlags	flags
955		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,							// VkPrimitiveTopology						topology
956		VK_FALSE														// VkBool32									primitiveRestartEnable
957	};
958
959	const VkPipelineViewportStateCreateInfo viewportStateCreateInfo
960	{
961		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType							sType
962		DE_NULL,														// const void*								pNext
963		(VkPipelineViewportStateCreateFlags)0,							// VkPipelineViewportStateCreateFlags		flags
964		(deUint32)viewportVect.size(),									// deUint32									viewportCount
965		viewportVect.data(),											// const VkViewport*						pViewports
966		(deUint32)scissorVect.size(),									// deUint32									scissorCount
967		scissorVect.data()												// const VkRect2D*							pScissors
968	};
969
970	const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfoDefault
971	{
972		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType							sType
973		DE_NULL,														// const void*								pNext
974		0u,																// VkPipelineRasterizationStateCreateFlags	flags
975		VK_FALSE,														// VkBool32									depthClampEnable
976		VK_FALSE,														// VkBool32									rasterizerDiscardEnable
977		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode
978		VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode
979		VK_FRONT_FACE_COUNTER_CLOCKWISE,								// VkFrontFace								frontFace
980		VK_FALSE,														// VkBool32									depthBiasEnable
981		0.0f,															// float									depthBiasConstantFactor
982		0.0f,															// float									depthBiasClamp
983		0.0f,															// float									depthBiasSlopeFactor
984		1.0f															// float									lineWidth
985	};
986
987	const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfoDefault
988	{
989		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,		// VkStructureType							sType
990		DE_NULL,														// const void*								pNext
991		0u,																// VkPipelineMultisampleStateCreateFlags	flags
992		VK_SAMPLE_COUNT_1_BIT,											// VkSampleCountFlagBits					rasterizationSamples
993		VK_FALSE,														// VkBool32									sampleShadingEnable
994		1.0f,															// float									minSampleShading
995		DE_NULL,														// const VkSampleMask*						pSampleMask
996		VK_FALSE,														// VkBool32									alphaToCoverageEnable
997		VK_FALSE														// VkBool32									alphaToOneEnable
998	};
999
1000	const VkStencilOpState stencilOpState
1001	{
1002		VK_STENCIL_OP_KEEP,												// VkStencilOp		failOp
1003		VK_STENCIL_OP_KEEP,												// VkStencilOp		passOp
1004		VK_STENCIL_OP_KEEP,												// VkStencilOp		depthFailOp
1005		VK_COMPARE_OP_NEVER,											// VkCompareOp		compareOp
1006		0,																// deUint32			compareMask
1007		0,																// deUint32			writeMask
1008		0																// deUint32			reference
1009	};
1010
1011	const VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfoDefault
1012	{
1013		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,		// VkStructureType							sType
1014		DE_NULL,														// const void*								pNext
1015		0u,																// VkPipelineDepthStencilStateCreateFlags	flags
1016		VK_FALSE,														// VkBool32									depthTestEnable
1017		VK_FALSE,														// VkBool32									depthWriteEnable
1018		VK_COMPARE_OP_LESS_OR_EQUAL,									// VkCompareOp								depthCompareOp
1019		VK_FALSE,														// VkBool32									depthBoundsTestEnable
1020		VK_FALSE,														// VkBool32									stencilTestEnable
1021		stencilOpState,													// VkStencilOpState							front
1022		stencilOpState,													// VkStencilOpState							back
1023		0.0f,															// float									minDepthBounds
1024		1.0f,															// float									maxDepthBounds
1025	};
1026
1027	const VkPipelineColorBlendAttachmentState colorBlendAttachmentState
1028	{
1029		VK_FALSE,														// VkBool32					blendEnable
1030		VK_BLEND_FACTOR_ZERO,											// VkBlendFactor			srcColorBlendFactor
1031		VK_BLEND_FACTOR_ZERO,											// VkBlendFactor			dstColorBlendFactor
1032		VK_BLEND_OP_ADD,												// VkBlendOp				colorBlendOp
1033		VK_BLEND_FACTOR_ZERO,											// VkBlendFactor			srcAlphaBlendFactor
1034		VK_BLEND_FACTOR_ZERO,											// VkBlendFactor			dstAlphaBlendFactor
1035		VK_BLEND_OP_ADD,												// VkBlendOp				alphaBlendOp
1036		VK_COLOR_COMPONENT_R_BIT										// VkColorComponentFlags	colorWriteMask
1037		| VK_COLOR_COMPONENT_G_BIT
1038		| VK_COLOR_COMPONENT_B_BIT
1039		| VK_COLOR_COMPONENT_A_BIT
1040	};
1041
1042	const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfoDefault
1043	{
1044		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,		// VkStructureType								sType
1045		DE_NULL,														// const void*									pNext
1046		0u,																// VkPipelineColorBlendStateCreateFlags			flags
1047		VK_FALSE,														// VkBool32										logicOpEnable
1048		VK_LOGIC_OP_CLEAR,												// VkLogicOp									logicOp
1049		1u,																// deUint32										attachmentCount
1050		&colorBlendAttachmentState,										// const VkPipelineColorBlendAttachmentState*	pAttachments
1051		{ 0.0f, 0.0f, 0.0f, 0.0f }										// float										blendConstants[4]
1052	};
1053
1054	VkGraphicsPipelineCreateInfo pipelineCreateInfo
1055	{
1056		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,													// VkStructureType									sType
1057		pNext,																								// const void*										pNext
1058		(useDensityMapAttachment ?
1059			deUint32(VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT) :
1060			0u),																							// VkPipelineCreateFlags							flags
1061		(deUint32)pipelineShaderStageParams.size(),															// deUint32											stageCount
1062		&pipelineShaderStageParams[0],																		// const VkPipelineShaderStageCreateInfo*			pStages
1063		&vertexInputStateCreateInfo,																		// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState
1064		&inputAssemblyStateCreateInfo,																		// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState
1065		DE_NULL,																							// const VkPipelineTessellationStateCreateInfo*		pTessellationState
1066		&viewportStateCreateInfo,																			// const VkPipelineViewportStateCreateInfo*			pViewportState
1067		&rasterizationStateCreateInfoDefault,																// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState
1068		multisampleStateCreateInfo ? multisampleStateCreateInfo: &multisampleStateCreateInfoDefault,		// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState
1069		&depthStencilStateCreateInfoDefault,																// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState
1070		&colorBlendStateCreateInfoDefault,																	// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState
1071		DE_NULL,																							// const VkPipelineDynamicStateCreateInfo*			pDynamicState
1072		pipelineLayout,																						// VkPipelineLayout									layout
1073		renderPass,																							// VkRenderPass										renderPass
1074		subpass,																							// deUint32											subpass
1075		DE_NULL,																							// VkPipeline										basePipelineHandle
1076		0																									// deInt32											basePipelineIndex;
1077	};
1078
1079	VkPipelineCreateFlags2CreateInfoKHR pipelineFlags2CreateInfo {};
1080	if (useDensityMapAttachment && useMaintenance5)
1081	{
1082		pipelineFlags2CreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CREATE_FLAGS_2_CREATE_INFO_KHR;
1083		pipelineFlags2CreateInfo.flags = VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT;
1084		pipelineFlags2CreateInfo.pNext = pipelineCreateInfo.pNext;
1085		pipelineCreateInfo.pNext = &pipelineFlags2CreateInfo;
1086		pipelineCreateInfo.flags = 0;
1087	}
1088
1089	return createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
1090}
1091
1092class FragmentDensityMapTest : public vkt::TestCase
1093{
1094public:
1095							FragmentDensityMapTest	(tcu::TestContext&	testContext,
1096													 const std::string&	name,
1097													 const TestParams&	testParams);
1098	virtual void			initPrograms			(SourceCollections&	sourceCollections) const;
1099	virtual TestInstance*	createInstance			(Context&			context) const;
1100	virtual void			checkSupport			(Context&			context) const;
1101
1102private:
1103	const TestParams		m_testParams;
1104};
1105
1106class FragmentDensityMapTestInstance : public vkt::TestInstance
1107{
1108public:
1109									FragmentDensityMapTestInstance			(Context&			context,
1110																			 const TestParams&	testParams);
1111	virtual tcu::TestStatus			iterate									(void);
1112
1113private:
1114
1115	typedef std::shared_ptr<RenderPassWrapperBase> RenderPassWrapperBasePtr;
1116
1117	void							drawDynamicDensityMap					(VkCommandBuffer cmdBuffer);
1118	void							drawSubsampledImage						(VkCommandBuffer cmdBuffer);
1119	void							drawResampleSubsampledImage				(VkCommandBuffer cmdBuffer);
1120	void							drawCopySubsampledImage					(VkCommandBuffer cmdBuffer);
1121	void							createCommandBufferForRenderpass		(RenderPassWrapperBasePtr	renderPassWrapper,
1122																			 const VkExtent3D&			colorImageSize,
1123																			 const VkRect2D&			dynamicDensityMapRenderArea,
1124																			 const VkRect2D&			colorImageRenderArea,
1125																			 const VkRect2D&			outputRenderArea);
1126	void							createCommandBufferForDynamicRendering	(const VkRect2D&			dynamicDensityMapRenderArea,
1127																			 const VkRect2D&			colorImageRenderArea,
1128																			 const VkRect2D&			outputRenderArea,
1129																			 const VkDevice&			vkDevice);
1130	tcu::TestStatus					verifyImage								(void);
1131
1132private:
1133
1134	typedef de::SharedPtr<Unique<VkSampler> >	VkSamplerSp;
1135	typedef de::SharedPtr<Unique<VkImage> >		VkImageSp;
1136	typedef de::SharedPtr<Allocation>			AllocationSp;
1137	typedef de::SharedPtr<Unique<VkImageView> >	VkImageViewSp;
1138
1139	TestParams						m_testParams;
1140	tcu::UVec2						m_renderSize;
1141	tcu::Vec2						m_densityValue;
1142	deUint32						m_viewMask;
1143
1144	Move<VkCommandPool>				m_cmdPool;
1145
1146	std::vector<VkImageSp>			m_densityMapImages;
1147	std::vector<AllocationSp>		m_densityMapImageAllocs;
1148	std::vector<VkImageViewSp>		m_densityMapImageViews;
1149
1150	Move<VkImage>					m_colorImage;
1151	de::MovePtr<Allocation>			m_colorImageAlloc;
1152	Move<VkImageView>				m_colorImageView;
1153
1154	Move<VkImage>					m_colorCopyImage;
1155	de::MovePtr<Allocation>			m_colorCopyImageAlloc;
1156	Move<VkImageView>				m_colorCopyImageView;
1157
1158	Move<VkImage>					m_colorResolvedImage;
1159	de::MovePtr<Allocation>			m_colorResolvedImageAlloc;
1160	Move<VkImageView>				m_colorResolvedImageView;
1161
1162	Move<VkImage>					m_outputImage;
1163	de::MovePtr<Allocation>			m_outputImageAlloc;
1164	Move<VkImageView>				m_outputImageView;
1165
1166	std::vector<VkSamplerSp>		m_colorSamplers;
1167
1168	Move<VkRenderPass>				m_renderPassProduceDynamicDensityMap;
1169	Move<VkRenderPass>				m_renderPassProduceSubsampledImage;
1170	Move<VkRenderPass>				m_renderPassUpdateSubsampledImage;
1171	Move<VkRenderPass>				m_renderPassOutputSubsampledImage;
1172	Move<VkFramebuffer>				m_framebufferProduceDynamicDensityMap;
1173	Move<VkFramebuffer>				m_framebufferProduceSubsampledImage;
1174	Move<VkFramebuffer>				m_framebufferUpdateSubsampledImage;
1175	Move<VkFramebuffer>				m_framebufferOutputSubsampledImage;
1176
1177	Move<VkDescriptorSetLayout>		m_descriptorSetLayoutProduceSubsampled;
1178
1179	Move<VkDescriptorSetLayout>		m_descriptorSetLayoutOperateOnSubsampledImage;
1180	Move<VkDescriptorPool>			m_descriptorPoolOperateOnSubsampledImage;
1181	Move<VkDescriptorSet>			m_descriptorSetOperateOnSubsampledImage;
1182
1183	Move<VkDescriptorSetLayout>		m_descriptorSetLayoutOutputSubsampledImage;
1184	Move<VkDescriptorPool>			m_descriptorPoolOutputSubsampledImage;
1185	Move<VkDescriptorSet>			m_descriptorSetOutputSubsampledImage;
1186
1187	Move<VkShaderModule>			m_vertexCommonShaderModule;
1188	Move<VkShaderModule>			m_fragmentShaderModuleProduceSubsampledImage;
1189	Move<VkShaderModule>			m_fragmentShaderModuleCopySubsampledImage;
1190	Move<VkShaderModule>			m_fragmentShaderModuleUpdateSubsampledImage;
1191	Move<VkShaderModule>			m_fragmentShaderModuleOutputSubsampledImage;
1192
1193	std::vector<Vertex4RGBA>		m_verticesDDM;
1194	Move<VkBuffer>					m_vertexBufferDDM;
1195	de::MovePtr<Allocation>			m_vertexBufferAllocDDM;
1196
1197	std::vector<Vertex4RGBA>		m_vertices;
1198	Move<VkBuffer>					m_vertexBuffer;
1199	de::MovePtr<Allocation>			m_vertexBufferAlloc;
1200
1201	std::vector<Vertex4RGBA>		m_verticesOutput;
1202	Move<VkBuffer>					m_vertexBufferOutput;
1203	de::MovePtr<Allocation>			m_vertexBufferOutputAlloc;
1204
1205	Move<VkPipelineLayout>			m_pipelineLayoutNoDescriptors;
1206	Move<VkPipelineLayout>			m_pipelineLayoutOperateOnSubsampledImage;
1207	Move<VkPipelineLayout>			m_pipelineLayoutOutputSubsampledImage;
1208	Move<VkPipeline>				m_graphicsPipelineProduceDynamicDensityMap;
1209	Move<VkPipeline>				m_graphicsPipelineProduceSubsampledImage;
1210	Move<VkPipeline>				m_graphicsPipelineCopySubsampledImage;
1211	Move<VkPipeline>				m_graphicsPipelineUpdateSubsampledImage;
1212	Move<VkPipeline>				m_graphicsPipelineOutputSubsampledImage;
1213
1214	Move<VkCommandBuffer>			m_cmdBuffer;
1215	Move<VkCommandBuffer>			m_dynamicDensityMapSecCmdBuffer;
1216	Move<VkCommandBuffer>			m_subsampledImageSecCmdBuffer;
1217	Move<VkCommandBuffer>			m_resampleSubsampledImageSecCmdBuffer;
1218	Move<VkCommandBuffer>			m_copySubsampledImageSecCmdBuffer;
1219};
1220
1221FragmentDensityMapTest::FragmentDensityMapTest (tcu::TestContext&	testContext,
1222												const std::string&	name,
1223												const TestParams&	testParams)
1224	: vkt::TestCase	(testContext, name)
1225	, m_testParams	(testParams)
1226{
1227	DE_ASSERT(testParams.samplersCount > 0);
1228}
1229
1230void FragmentDensityMapTest::initPrograms(SourceCollections& sourceCollections) const
1231{
1232	const std::string vertSourceTemplate(
1233		"#version 450\n"
1234		"#extension GL_EXT_multiview : enable\n"
1235		"${EXTENSIONS}"
1236		"layout(location = 0) in  vec4 inPosition;\n"
1237		"layout(location = 1) in  vec4 inUV;\n"
1238		"layout(location = 2) in  vec4 inColor;\n"
1239		"layout(location = 0) out vec4 outUV;\n"
1240		"layout(location = 1) out vec4 outColor;\n"
1241		"out gl_PerVertex\n"
1242		"{\n"
1243		"  vec4 gl_Position;\n"
1244		"};\n"
1245		"void main(void)\n"
1246		"{\n"
1247		"	gl_Position = inPosition;\n"
1248		"	outUV = inUV;\n"
1249		"	outColor = inColor;\n"
1250		"	${OPERATION}"
1251		"}\n");
1252
1253	std::map<std::string, std::string> parameters
1254	{
1255		{"EXTENSIONS", ""},
1256		{"OPERATION", ""}
1257	};
1258	if (m_testParams.multiViewport)
1259	{
1260		parameters["EXTENSIONS"] = "#extension GL_ARB_shader_viewport_layer_array : enable\n";
1261		parameters["OPERATION"] = "gl_ViewportIndex = gl_ViewIndex;\n";
1262	}
1263	sourceCollections.glslSources.add("vert") << glu::VertexSource(tcu::StringTemplate(vertSourceTemplate).specialize(parameters));
1264
1265	sourceCollections.glslSources.add("frag_produce_subsampled") << glu::FragmentSource(
1266		"#version 450\n"
1267		"#extension GL_EXT_fragment_invocation_density : enable\n"
1268		"#extension GL_EXT_multiview : enable\n"
1269		"layout(location = 0) in vec4 inUV;\n"
1270		"layout(location = 1) in vec4 inColor;\n"
1271		"layout(location = 0) out vec4 fragColor;\n"
1272		"void main(void)\n"
1273		"{\n"
1274		"	fragColor = vec4(inColor.x, inColor.y, 1.0/float(gl_FragSizeEXT.x), 1.0/(gl_FragSizeEXT.y));\n"
1275		"}\n"
1276	);
1277
1278	sourceCollections.glslSources.add("frag_update_subsampled") << glu::FragmentSource(
1279		"#version 450\n"
1280		"#extension GL_EXT_fragment_invocation_density : enable\n"
1281		"#extension GL_EXT_multiview : enable\n"
1282		"layout(location = 0) in vec4 inUV;\n"
1283		"layout(location = 1) in vec4 inColor;\n"
1284		"layout(location = 0) out vec4 fragColor;\n"
1285		"void main(void)\n"
1286		"{\n"
1287		"	if (gl_FragCoord.y < 0.5)\n"
1288		"		discard;\n"
1289		"	fragColor = vec4(inColor.x, inColor.y, 1.0/float(gl_FragSizeEXT.x), 1.0/(gl_FragSizeEXT.y));\n"
1290		"}\n"
1291	);
1292
1293	sourceCollections.glslSources.add("frag_copy_subsampled") << glu::FragmentSource(
1294		"#version 450\n"
1295		"#extension GL_EXT_fragment_invocation_density : enable\n"
1296		"#extension GL_EXT_multiview : enable\n"
1297		"layout(location = 0) in vec4 inUV;\n"
1298		"layout(location = 1) in vec4 inColor;\n"
1299		"layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput inputAtt;\n"
1300		"layout(location = 0) out vec4 fragColor;\n"
1301		"void main(void)\n"
1302		"{\n"
1303		"	fragColor = subpassLoad(inputAtt);\n"
1304		"}\n"
1305	);
1306
1307	sourceCollections.glslSources.add("frag_copy_subsampled_ms") << glu::FragmentSource(
1308		"#version 450\n"
1309		"#extension GL_EXT_fragment_invocation_density : enable\n"
1310		"#extension GL_EXT_multiview : enable\n"
1311		"layout(location = 0) in vec4 inUV;\n"
1312		"layout(location = 1) in vec4 inColor;\n"
1313		"layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInputMS inputAtt;\n"
1314		"layout(location = 0) out vec4 fragColor;\n"
1315		"void main(void)\n"
1316		"{\n"
1317		"	fragColor = subpassLoad(inputAtt, gl_SampleID);\n"
1318		"}\n"
1319	);
1320
1321	const char* samplersDefTemplate =
1322		"layout(binding = ${BINDING})  uniform ${SAMPLER} subsampledImage${BINDING};\n";
1323	const char* sumColorsTemplate =
1324		"	fragColor += texture(subsampledImage${BINDING}, inUV.${COMPONENTS});\n";
1325
1326	const char* densitymapOutputTemplate =
1327		"#version 450\n"
1328		"layout(location = 0) in vec4 inUV;\n"
1329		"layout(location = 1) in vec4 inColor;\n"
1330		"${SAMPLERS_DEF}"
1331		"layout(location = 0) out vec4 fragColor;\n"
1332		"void main(void)\n"
1333		"{\n"
1334		"	fragColor = vec4(0);\n"
1335		"${SUM_COLORS}"
1336		"	fragColor /= float(${COUNT});\n"
1337		"}\n";
1338
1339	parameters =
1340	{
1341		{ "SAMPLER",		"" },
1342		{ "BINDING",		"" },
1343		{ "COMPONENTS",		"" },
1344		{ "COUNT",			std::to_string(m_testParams.samplersCount) },
1345		{ "SAMPLERS_DEF",	"" },
1346		{ "SUM_COLORS",		"" },
1347	};
1348
1349	std::string sampler2dDefs;
1350	std::string sampler2dSumColors;
1351	std::string sampler2dArrayDefs;
1352	std::string sampler2dArraySumColors;
1353	for (deUint32 samplerIndex = 0; samplerIndex < m_testParams.samplersCount; ++samplerIndex)
1354	{
1355		parameters["BINDING"]		 = std::to_string(samplerIndex);
1356
1357		parameters["COMPONENTS"]	 = "xy";
1358		parameters["SAMPLER"]		 = "sampler2D";
1359		sampler2dDefs				+= tcu::StringTemplate(samplersDefTemplate).specialize(parameters);
1360		sampler2dSumColors			+= tcu::StringTemplate(sumColorsTemplate).specialize(parameters);
1361
1362		parameters["COMPONENTS"]	 = "xyz";
1363		parameters["SAMPLER"]		 = "sampler2DArray";
1364		sampler2dArrayDefs			+= tcu::StringTemplate(samplersDefTemplate).specialize(parameters);
1365		sampler2dArraySumColors		+= tcu::StringTemplate(sumColorsTemplate).specialize(parameters);
1366	}
1367
1368	parameters["SAMPLERS_DEF"]	= sampler2dDefs;
1369	parameters["SUM_COLORS"]	= sampler2dSumColors;
1370	sourceCollections.glslSources.add("frag_output_2d")
1371		<< glu::FragmentSource(tcu::StringTemplate(densitymapOutputTemplate).specialize(parameters));
1372
1373	parameters["SAMPLERS_DEF"]	= sampler2dArrayDefs;
1374	parameters["SUM_COLORS"]	= sampler2dArraySumColors;
1375	sourceCollections.glslSources.add("frag_output_2darray")
1376		<< glu::FragmentSource(tcu::StringTemplate(densitymapOutputTemplate).specialize(parameters));
1377}
1378
1379TestInstance* FragmentDensityMapTest::createInstance(Context& context) const
1380{
1381	return new FragmentDensityMapTestInstance(context, m_testParams);
1382}
1383
1384void FragmentDensityMapTest::checkSupport(Context& context) const
1385{
1386	const InstanceInterface&	vki					= context.getInstanceInterface();
1387	const VkPhysicalDevice		vkPhysicalDevice	= context.getPhysicalDevice();
1388
1389	context.requireDeviceFunctionality("VK_EXT_fragment_density_map");
1390
1391	if (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
1392		context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
1393
1394	if (m_testParams.imagelessFramebuffer)
1395		context.requireDeviceFunctionality("VK_KHR_imageless_framebuffer");
1396
1397	if (m_testParams.useMaintenance5)
1398		context.requireDeviceFunctionality("VK_KHR_maintenance5");
1399
1400	VkPhysicalDeviceFragmentDensityMapFeaturesEXT		fragmentDensityMapFeatures		= initVulkanStructure();
1401	VkPhysicalDeviceFragmentDensityMap2FeaturesEXT		fragmentDensityMap2Features		= initVulkanStructure(&fragmentDensityMapFeatures);
1402	VkPhysicalDeviceFeatures2KHR						features2						= initVulkanStructure(&fragmentDensityMap2Features);
1403
1404	context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
1405
1406	const auto& fragmentDensityMap2Properties	= context.getFragmentDensityMap2PropertiesEXT();
1407
1408	if (!fragmentDensityMapFeatures.fragmentDensityMap)
1409		TCU_THROW(NotSupportedError, "fragmentDensityMap feature is not supported");
1410	if (m_testParams.dynamicDensityMap && !fragmentDensityMapFeatures.fragmentDensityMapDynamic)
1411		TCU_THROW(NotSupportedError, "fragmentDensityMapDynamic feature is not supported");
1412	if (m_testParams.nonSubsampledImages && !fragmentDensityMapFeatures.fragmentDensityMapNonSubsampledImages)
1413		TCU_THROW(NotSupportedError, "fragmentDensityMapNonSubsampledImages feature is not supported");
1414
1415	if (m_testParams.deferredDensityMap)
1416	{
1417		context.requireDeviceFunctionality("VK_EXT_fragment_density_map2");
1418		if (!fragmentDensityMap2Features.fragmentDensityMapDeferred)
1419			TCU_THROW(NotSupportedError, "fragmentDensityMapDeferred feature is not supported");
1420	}
1421	if (m_testParams.subsampledLoads)
1422	{
1423		context.requireDeviceFunctionality("VK_EXT_fragment_density_map2");
1424		if (!fragmentDensityMap2Properties.subsampledLoads)
1425			TCU_THROW(NotSupportedError, "subsampledLoads property is not supported");
1426	}
1427	if (m_testParams.coarseReconstruction)
1428	{
1429		context.requireDeviceFunctionality("VK_EXT_fragment_density_map2");
1430		if (!fragmentDensityMap2Properties.subsampledCoarseReconstructionEarlyAccess)
1431			TCU_THROW(NotSupportedError, "subsampledCoarseReconstructionEarlyAccess property is not supported");
1432	}
1433
1434	if (m_testParams.viewCount > 1)
1435	{
1436		context.requireDeviceFunctionality("VK_KHR_multiview");
1437		if (!context.getMultiviewFeatures().multiview)
1438			TCU_THROW(NotSupportedError, "Implementation does not support multiview feature");
1439
1440		if (m_testParams.viewCount > 2)
1441		{
1442			context.requireDeviceFunctionality("VK_EXT_fragment_density_map2");
1443			if (m_testParams.viewCount > fragmentDensityMap2Properties.maxSubsampledArrayLayers)
1444				TCU_THROW(NotSupportedError, "Maximum number of VkImageView array layers for usages supporting subsampled samplers is to small");
1445		}
1446	}
1447
1448	if (m_testParams.multiViewport)
1449	{
1450		context.requireDeviceFunctionality("VK_EXT_shader_viewport_index_layer");
1451		if (!context.getDeviceFeatures().multiViewport)
1452			TCU_THROW(NotSupportedError, "multiViewport not supported");
1453	}
1454
1455	if (!m_testParams.nonSubsampledImages && (m_testParams.samplersCount > 1))
1456	{
1457		context.requireDeviceFunctionality("VK_EXT_fragment_density_map2");
1458		if (m_testParams.samplersCount > fragmentDensityMap2Properties.maxDescriptorSetSubsampledSamplers)
1459			TCU_THROW(NotSupportedError, "Required number of subsampled samplers is not supported");
1460	}
1461
1462	vk::VkImageUsageFlags	colorImageUsage			= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
1463	if (m_testParams.makeCopy)
1464		colorImageUsage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1465
1466	deUint32				colorImageCreateFlags	= m_testParams.nonSubsampledImages ? 0u : (deUint32)VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT;
1467	VkImageFormatProperties	imageFormatProperties	(getPhysicalDeviceImageFormatProperties(vki, vkPhysicalDevice, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, colorImageUsage, colorImageCreateFlags));
1468
1469	if ((imageFormatProperties.sampleCounts & m_testParams.colorSamples) == 0)
1470		TCU_THROW(NotSupportedError, "Color image type not supported");
1471
1472	if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
1473		!context.getPortabilitySubsetFeatures().multisampleArrayImage &&
1474		(m_testParams.colorSamples != VK_SAMPLE_COUNT_1_BIT) && (m_testParams.viewCount != 1))
1475	{
1476		TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Implementation does not support image array with multiple samples per texel");
1477	}
1478}
1479
1480FragmentDensityMapTestInstance::FragmentDensityMapTestInstance(Context&				context,
1481															   const TestParams&	testParams)
1482	: vkt::TestInstance	(context)
1483	, m_testParams		(testParams)
1484{
1485	m_renderSize		= tcu::UVec2(deFloorFloatToInt32(m_testParams.renderMultiplier * static_cast<float>(m_testParams.densityMapSize.x())),
1486									 deFloorFloatToInt32(m_testParams.renderMultiplier * static_cast<float>(m_testParams.densityMapSize.y())));
1487	m_densityValue		= tcu::Vec2(1.0f / static_cast<float>(m_testParams.fragmentArea.x()),
1488									1.0f / static_cast<float>(m_testParams.fragmentArea.y()));
1489	m_viewMask			= (m_testParams.viewCount > 1) ? ((1u << m_testParams.viewCount) - 1u) : 0u;
1490
1491	const DeviceInterface&		vk							= m_context.getDeviceInterface();
1492	const VkDevice				vkDevice					= getDevice(m_context);
1493	const VkPhysicalDevice		vkPhysicalDevice			= m_context.getPhysicalDevice();
1494	const deUint32				queueFamilyIndex			= m_context.getUniversalQueueFamilyIndex();
1495	const VkQueue				queue						= getDeviceQueue(vk, vkDevice, queueFamilyIndex, 0);
1496	SimpleAllocator				memAlloc					(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), vkPhysicalDevice));
1497	const VkComponentMapping	componentMappingRGBA		= makeComponentMappingRGBA();
1498	RenderPassWrapperBasePtr	renderPassWrapper;
1499
1500	// calculate all image sizes, image usage flags, view types etc.
1501	deUint32						densitiMapCount				= 1 + m_testParams.subsampledLoads;
1502	VkExtent3D						densityMapImageSize			{ m_testParams.densityMapSize.x(), m_testParams.densityMapSize.y(), 1 };
1503	deUint32						densityMapImageLayers		= m_testParams.viewCount;
1504	VkImageViewType					densityMapImageViewType		= (m_testParams.viewCount > 1) ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D;
1505	vk::VkImageUsageFlags			densityMapImageUsage		= VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1506	const VkImageSubresourceRange	densityMapSubresourceRange	= { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, densityMapImageLayers };
1507	deUint32						densityMapImageViewFlags	= 0u;
1508
1509	const VkFormat					colorImageFormat			= VK_FORMAT_R8G8B8A8_UNORM;
1510	VkExtent3D						colorImageSize				{ m_renderSize.x() / m_testParams.viewCount, m_renderSize.y(), 1 };
1511	deUint32						colorImageLayers			= densityMapImageLayers;
1512	VkImageViewType					colorImageViewType			= densityMapImageViewType;
1513	vk::VkImageUsageFlags			colorImageUsage				= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
1514	deUint32						colorImageCreateFlags		= m_testParams.nonSubsampledImages ? 0u : (deUint32)VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT;
1515	const VkImageSubresourceRange	colorSubresourceRange		= { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, colorImageLayers };
1516	bool							isColorImageMultisampled	= m_testParams.colorSamples != VK_SAMPLE_COUNT_1_BIT;
1517	bool							isDynamicRendering			= m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING;
1518
1519	VkExtent3D						outputImageSize				{ m_renderSize.x(), m_renderSize.y(), 1 };
1520	const VkImageSubresourceRange	outputSubresourceRange		{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u };
1521
1522	if (m_testParams.dynamicDensityMap)
1523	{
1524		DE_ASSERT(!m_testParams.subsampledLoads);
1525
1526		densityMapImageUsage		= VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1527		densityMapImageViewFlags	= (deUint32)VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DYNAMIC_BIT_EXT;
1528	}
1529	else if (m_testParams.deferredDensityMap)
1530		densityMapImageViewFlags	= (deUint32)VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DEFERRED_BIT_EXT;
1531	if (m_testParams.makeCopy)
1532		colorImageUsage				|= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1533
1534	// Create subsampled color image
1535	prepareImageAndImageView(vk, vkDevice, memAlloc, colorImageCreateFlags, colorImageFormat,
1536		colorImageSize, colorImageLayers, m_testParams.colorSamples,
1537		colorImageUsage, queueFamilyIndex, 0u, colorImageViewType,
1538		componentMappingRGBA, colorSubresourceRange, m_colorImage, m_colorImageAlloc, m_colorImageView);
1539
1540	// Create subsampled color image for resolve operation ( when multisampling is used )
1541	if (isColorImageMultisampled)
1542	{
1543		prepareImageAndImageView(vk, vkDevice, memAlloc, colorImageCreateFlags, colorImageFormat,
1544			colorImageSize, colorImageLayers, VK_SAMPLE_COUNT_1_BIT,
1545			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, queueFamilyIndex, 0u, colorImageViewType,
1546			componentMappingRGBA, colorSubresourceRange, m_colorResolvedImage, m_colorResolvedImageAlloc, m_colorResolvedImageView);
1547	}
1548
1549	// Create subsampled image copy
1550	if (m_testParams.makeCopy)
1551	{
1552		prepareImageAndImageView(vk, vkDevice, memAlloc, colorImageCreateFlags, colorImageFormat,
1553			colorImageSize, colorImageLayers, m_testParams.colorSamples,
1554			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, queueFamilyIndex, 0u, colorImageViewType,
1555			componentMappingRGBA, colorSubresourceRange, m_colorCopyImage, m_colorCopyImageAlloc, m_colorCopyImageView);
1556	}
1557
1558	// Create output image ( data from subsampled color image will be copied into it using sampler with VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT )
1559	prepareImageAndImageView(vk, vkDevice, memAlloc, 0u, colorImageFormat,
1560		outputImageSize, 1u, VK_SAMPLE_COUNT_1_BIT,
1561		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, queueFamilyIndex, 0u, VK_IMAGE_VIEW_TYPE_2D,
1562		componentMappingRGBA, outputSubresourceRange, m_outputImage, m_outputImageAlloc, m_outputImageView);
1563
1564	// Create density map image/images
1565	for (deUint32 mapIndex = 0; mapIndex < densitiMapCount; ++mapIndex)
1566	{
1567		Move<VkImage>			densityMapImage;
1568		de::MovePtr<Allocation>	densityMapImageAlloc;
1569		Move<VkImageView>		densityMapImageView;
1570
1571		prepareImageAndImageView(vk, vkDevice, memAlloc, 0u, m_testParams.densityMapFormat,
1572			densityMapImageSize, densityMapImageLayers, VK_SAMPLE_COUNT_1_BIT,
1573			densityMapImageUsage, queueFamilyIndex, densityMapImageViewFlags, densityMapImageViewType,
1574			componentMappingRGBA, densityMapSubresourceRange, densityMapImage, densityMapImageAlloc, densityMapImageView);
1575
1576		m_densityMapImages.push_back(VkImageSp(new Unique<VkImage>(densityMapImage)));
1577		m_densityMapImageAllocs.push_back(AllocationSp(densityMapImageAlloc.release()));
1578		m_densityMapImageViews.push_back(VkImageViewSp(new Unique<VkImageView>(densityMapImageView)));
1579	}
1580
1581	// Create and fill staging buffer, copy its data to density map image
1582	if (!m_testParams.dynamicDensityMap)
1583	{
1584		tcu::TextureFormat				densityMapTextureFormat = vk::mapVkFormat(m_testParams.densityMapFormat);
1585		VkDeviceSize					stagingBufferSize		= tcu::getPixelSize(densityMapTextureFormat) * densityMapImageSize.width * densityMapImageSize.height * densityMapImageLayers;
1586		const vk::VkBufferCreateInfo	stagingBufferCreateInfo
1587		{
1588			vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1589			DE_NULL,
1590			0u,									// flags
1591			stagingBufferSize,					// size
1592			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,	// usage
1593			vk::VK_SHARING_MODE_EXCLUSIVE,		// sharingMode
1594			0u,									// queueFamilyCount
1595			DE_NULL,							// pQueueFamilyIndices
1596		};
1597		vk::Move<vk::VkBuffer>			stagingBuffer		= vk::createBuffer(vk, vkDevice, &stagingBufferCreateInfo);
1598		const vk::VkMemoryRequirements	stagingRequirements = vk::getBufferMemoryRequirements(vk, vkDevice, *stagingBuffer);
1599		de::MovePtr<vk::Allocation>		stagingAllocation	= memAlloc.allocate(stagingRequirements, MemoryRequirement::HostVisible);
1600		VK_CHECK(vk.bindBufferMemory(vkDevice, *stagingBuffer, stagingAllocation->getMemory(), stagingAllocation->getOffset()));
1601		tcu::PixelBufferAccess			stagingBufferAccess	(densityMapTextureFormat, densityMapImageSize.width, densityMapImageSize.height, densityMapImageLayers, stagingAllocation->getHostPtr());
1602		tcu::Vec4						fragmentArea		(m_densityValue.x(), m_densityValue.y(), 0.0f, 1.0f);
1603
1604		for (deUint32 mapIndex = 0; mapIndex < densitiMapCount; ++mapIndex)
1605		{
1606			// Fill staging buffer with one color
1607			tcu::clear(stagingBufferAccess, fragmentArea);
1608			flushAlloc(vk, vkDevice, *stagingAllocation);
1609
1610			copyBufferToImage
1611			(
1612				vk, vkDevice, queue, queueFamilyIndex,
1613				*stagingBuffer, stagingBufferSize,
1614				densityMapImageSize, densityMapImageLayers, **m_densityMapImages[mapIndex]
1615			);
1616
1617			std::swap(fragmentArea.m_data[0], fragmentArea.m_data[1]);
1618		}
1619	}
1620
1621	deUint32 samplerCreateFlags = (deUint32)VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT;
1622	if (m_testParams.coarseReconstruction)
1623		samplerCreateFlags		|= (deUint32)VK_SAMPLER_CREATE_SUBSAMPLED_COARSE_RECONSTRUCTION_BIT_EXT;
1624	if (m_testParams.nonSubsampledImages)
1625		samplerCreateFlags		= 0u;
1626
1627	const struct VkSamplerCreateInfo samplerInfo
1628	{
1629		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,			// sType
1630		DE_NULL,										// pNext
1631		(VkSamplerCreateFlags)samplerCreateFlags,		// flags
1632		VK_FILTER_NEAREST,								// magFilter
1633		VK_FILTER_NEAREST,								// minFilter
1634		VK_SAMPLER_MIPMAP_MODE_NEAREST,					// mipmapMode
1635		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			// addressModeU
1636		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			// addressModeV
1637		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			// addressModeW
1638		0.0f,											// mipLodBias
1639		VK_FALSE,										// anisotropyEnable
1640		1.0f,											// maxAnisotropy
1641		DE_FALSE,										// compareEnable
1642		VK_COMPARE_OP_ALWAYS,							// compareOp
1643		0.0f,											// minLod
1644		0.0f,											// maxLod
1645		VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,		// borderColor
1646		VK_FALSE,										// unnormalizedCoords
1647	};
1648
1649	// Create a sampler that are able to read from subsampled image
1650	// (more than one sampler is needed only for 4 maxDescriptorSetSubsampledSamplers tests)
1651	for (deUint32 samplerIndex = 0; samplerIndex < testParams.samplersCount; ++samplerIndex)
1652		m_colorSamplers.push_back(VkSamplerSp(new Unique<VkSampler>(createSampler(vk, vkDevice, &samplerInfo))));
1653
1654	if (!isDynamicRendering)
1655	{
1656		// Create render passes
1657		if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY)
1658			renderPassWrapper = RenderPassWrapperBasePtr(new RenderPassWrapper<RENDERING_TYPE_RENDERPASS_LEGACY>(vk, vkDevice, testParams));
1659		else
1660			renderPassWrapper = RenderPassWrapperBasePtr(new RenderPassWrapper<RENDERING_TYPE_RENDERPASS2>(vk, vkDevice, testParams));
1661
1662		if (testParams.dynamicDensityMap)
1663			m_renderPassProduceDynamicDensityMap = renderPassWrapper->createRenderPassProduceDynamicDensityMap(m_viewMask);
1664		m_renderPassProduceSubsampledImage = renderPassWrapper->createRenderPassProduceSubsampledImage(m_viewMask, testParams.makeCopy, false);
1665		if (testParams.subsampledLoads)
1666			m_renderPassUpdateSubsampledImage = renderPassWrapper->createRenderPassProduceSubsampledImage(m_viewMask, false, true);
1667		m_renderPassOutputSubsampledImage = renderPassWrapper->createRenderPassOutputSubsampledImage();
1668
1669		// Create framebuffers
1670		if (!testParams.imagelessFramebuffer)
1671		{
1672			if (testParams.dynamicDensityMap)
1673			{
1674				m_framebufferProduceDynamicDensityMap = createFrameBuffer(vk, vkDevice,
1675					*m_renderPassProduceDynamicDensityMap,
1676					densityMapImageSize,
1677					{ **m_densityMapImageViews[0] });
1678			}
1679
1680			std::vector<VkImageView> imageViewsProduceSubsampledImage = { *m_colorImageView };
1681			if (isColorImageMultisampled)
1682				imageViewsProduceSubsampledImage.push_back(*m_colorResolvedImageView);
1683			if (testParams.makeCopy)
1684				imageViewsProduceSubsampledImage.push_back(*m_colorCopyImageView);
1685			imageViewsProduceSubsampledImage.push_back(**m_densityMapImageViews[0]);
1686
1687			m_framebufferProduceSubsampledImage = createFrameBuffer(vk, vkDevice,
1688				*m_renderPassProduceSubsampledImage,
1689				colorImageSize,
1690				imageViewsProduceSubsampledImage);
1691
1692			if (testParams.subsampledLoads)
1693			{
1694				m_framebufferUpdateSubsampledImage = createFrameBuffer(vk, vkDevice,
1695					*m_renderPassUpdateSubsampledImage,
1696					colorImageSize,
1697					{ *m_colorImageView, **m_densityMapImageViews[1] });
1698			}
1699
1700			m_framebufferOutputSubsampledImage = createFrameBuffer(vk, vkDevice,
1701				*m_renderPassOutputSubsampledImage,
1702				outputImageSize,
1703				{ *m_outputImageView });
1704		}
1705		else // create same framebuffers as above but with VkFramebufferAttachmentsCreateInfo instead of image views
1706		{
1707			// helper lambda used to create VkFramebufferAttachmentImageInfo structure and reduce code size
1708			auto createFramebufferAttachmentImageInfo = [](VkImageCreateFlags createFlags, VkImageUsageFlags usageFlags, VkExtent3D& extent, deUint32 layerCount, const VkFormat* format)
1709			{
1710				return VkFramebufferAttachmentImageInfo
1711				{
1712					VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO,	// VkStructureType		sType;
1713					DE_NULL,												// const void*			pNext;
1714					createFlags,											// VkImageCreateFlags	flags;
1715					usageFlags,												// VkImageUsageFlags	usage;
1716					extent.width,											// deUint32				width;
1717					extent.height,											// deUint32				height;
1718					layerCount,												// deUint32				layerCount;
1719					1u,														// deUint32				viewFormatCount;
1720					format													// const VkFormat*		pViewFormats;
1721				};
1722			};
1723
1724			if (testParams.dynamicDensityMap)
1725			{
1726				m_framebufferProduceDynamicDensityMap = createImagelessFrameBuffer(vk, vkDevice,
1727					*m_renderPassProduceDynamicDensityMap,
1728					densityMapImageSize,
1729					{ createFramebufferAttachmentImageInfo(0u, densityMapImageUsage, densityMapImageSize, densityMapImageLayers, &m_testParams.densityMapFormat) });
1730			}
1731
1732			std::vector<VkFramebufferAttachmentImageInfo> attachmentInfoProduceSubsampledImage;
1733			attachmentInfoProduceSubsampledImage.reserve(4);
1734			attachmentInfoProduceSubsampledImage.push_back(
1735				createFramebufferAttachmentImageInfo((VkImageCreateFlags)colorImageCreateFlags,
1736					colorImageUsage,
1737					colorImageSize,
1738					colorImageLayers,
1739					&colorImageFormat));
1740			if (isColorImageMultisampled)
1741			{
1742				attachmentInfoProduceSubsampledImage.push_back(
1743					createFramebufferAttachmentImageInfo((VkImageCreateFlags)colorImageCreateFlags,
1744						VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
1745						colorImageSize,
1746						colorImageLayers,
1747						&colorImageFormat));
1748			}
1749			if (testParams.makeCopy)
1750			{
1751				attachmentInfoProduceSubsampledImage.push_back(
1752					createFramebufferAttachmentImageInfo((VkImageCreateFlags)colorImageCreateFlags,
1753						VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
1754						colorImageSize,
1755						colorImageLayers,
1756						&colorImageFormat));
1757			}
1758			attachmentInfoProduceSubsampledImage.push_back(
1759				createFramebufferAttachmentImageInfo((VkImageCreateFlags)colorImageCreateFlags,
1760					colorImageUsage,
1761					colorImageSize,
1762					colorImageLayers,
1763					&colorImageFormat));
1764
1765			m_framebufferProduceSubsampledImage = createImagelessFrameBuffer(vk, vkDevice,
1766				*m_renderPassProduceSubsampledImage,
1767				colorImageSize,
1768				attachmentInfoProduceSubsampledImage);
1769
1770			if (testParams.subsampledLoads)
1771			{
1772				m_framebufferUpdateSubsampledImage = createImagelessFrameBuffer(vk, vkDevice,
1773					*m_renderPassUpdateSubsampledImage,
1774					colorImageSize,
1775					{
1776						createFramebufferAttachmentImageInfo((VkImageCreateFlags)colorImageCreateFlags,
1777															 colorImageUsage,
1778															 colorImageSize,
1779															 colorImageLayers,
1780															 &colorImageFormat),
1781						createFramebufferAttachmentImageInfo(0u,
1782															 densityMapImageUsage,
1783															 densityMapImageSize,
1784															 densityMapImageLayers,
1785															 &m_testParams.densityMapFormat)
1786					});
1787			}
1788
1789			m_framebufferOutputSubsampledImage = createImagelessFrameBuffer(vk, vkDevice,
1790				*m_renderPassOutputSubsampledImage,
1791				outputImageSize,
1792				{ createFramebufferAttachmentImageInfo(0u,
1793													   VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1794													   outputImageSize,
1795													   1u,
1796													   &colorImageFormat) });
1797		}
1798	}
1799
1800	// Create pipeline layout for subpasses that do not use any descriptors
1801	{
1802		const VkPipelineLayoutCreateInfo pipelineLayoutParams
1803		{
1804			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType;
1805			DE_NULL,										// const void*					pNext;
1806			0u,												// VkPipelineLayoutCreateFlags	flags;
1807			0u,												// deUint32						setLayoutCount;
1808			DE_NULL,										// const VkDescriptorSetLayout*	pSetLayouts;
1809			0u,												// deUint32						pushConstantRangeCount;
1810			DE_NULL											// const VkPushConstantRange*	pPushConstantRanges;
1811		};
1812
1813		m_pipelineLayoutNoDescriptors = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1814	}
1815
1816	// Create pipeline layout for subpass that copies data or resamples subsampled image
1817	if (m_testParams.makeCopy || m_testParams.subsampledLoads)
1818	{
1819		m_descriptorSetLayoutOperateOnSubsampledImage =
1820			DescriptorSetLayoutBuilder()
1821			.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT, DE_NULL)
1822			.build(vk, vkDevice);
1823
1824		// Create and bind descriptor set
1825		m_descriptorPoolOperateOnSubsampledImage =
1826			DescriptorPoolBuilder()
1827			.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u)
1828			.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1829
1830		m_pipelineLayoutOperateOnSubsampledImage	= makePipelineLayout(vk, vkDevice, *m_descriptorSetLayoutOperateOnSubsampledImage);
1831		m_descriptorSetOperateOnSubsampledImage		= makeDescriptorSet(vk, vkDevice, *m_descriptorPoolOperateOnSubsampledImage, *m_descriptorSetLayoutOperateOnSubsampledImage);
1832
1833		const VkDescriptorImageInfo inputImageInfo =
1834		{
1835			DE_NULL,											// VkSampleri		sampler;
1836			*m_colorImageView,									// VkImageView		imageView;
1837			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL			// VkImageLayout	imageLayout;
1838		};
1839		DescriptorSetUpdateBuilder()
1840			.writeSingle(*m_descriptorSetOperateOnSubsampledImage, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &inputImageInfo)
1841			.update(vk, vkDevice);
1842	}
1843
1844	// Create pipeline layout for last render pass (output subsampled image)
1845	{
1846		DescriptorSetLayoutBuilder	descriptorSetLayoutBuilder;
1847		DescriptorPoolBuilder		descriptorPoolBuilder;
1848		for (deUint32 samplerIndex = 0; samplerIndex < testParams.samplersCount; ++samplerIndex)
1849		{
1850			descriptorSetLayoutBuilder.addSingleSamplerBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, &(*m_colorSamplers[samplerIndex]).get());
1851			descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, samplerIndex + 1u);
1852		}
1853
1854		m_descriptorSetLayoutOutputSubsampledImage	= descriptorSetLayoutBuilder.build(vk, vkDevice);
1855		m_descriptorPoolOutputSubsampledImage		= descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1856		m_pipelineLayoutOutputSubsampledImage		= makePipelineLayout(vk, vkDevice, *m_descriptorSetLayoutOutputSubsampledImage);
1857		m_descriptorSetOutputSubsampledImage		= makeDescriptorSet(vk, vkDevice, *m_descriptorPoolOutputSubsampledImage, *m_descriptorSetLayoutOutputSubsampledImage);
1858
1859		VkImageView srcImageView = *m_colorImageView;
1860		if (isColorImageMultisampled)
1861			srcImageView = *m_colorResolvedImageView;
1862		else if (m_testParams.makeCopy)
1863			srcImageView = *m_colorCopyImageView;
1864
1865		const VkDescriptorImageInfo inputImageInfo
1866		{
1867			DE_NULL,									// VkSampleri		sampler;
1868			srcImageView,								// VkImageView		imageView;
1869			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL	// VkImageLayout	imageLayout;
1870		};
1871
1872		DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
1873		for (deUint32 samplerIndex = 0; samplerIndex < testParams.samplersCount; ++samplerIndex)
1874			descriptorSetUpdateBuilder.writeSingle(*m_descriptorSetOutputSubsampledImage, DescriptorSetUpdateBuilder::Location::binding(samplerIndex), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &inputImageInfo);
1875		descriptorSetUpdateBuilder.update(vk, vkDevice);
1876	}
1877
1878	// Load vertex and fragment shaders
1879	auto& bc = m_context.getBinaryCollection();
1880	m_vertexCommonShaderModule						= createShaderModule(vk, vkDevice, bc.get("vert"), 0);
1881	m_fragmentShaderModuleProduceSubsampledImage	= createShaderModule(vk, vkDevice, bc.get("frag_produce_subsampled"), 0);
1882	if (m_testParams.makeCopy)
1883	{
1884		const char* moduleName = isColorImageMultisampled ? "frag_copy_subsampled_ms" : "frag_copy_subsampled";
1885		m_fragmentShaderModuleCopySubsampledImage = createShaderModule(vk, vkDevice, bc.get(moduleName), 0);
1886	}
1887	if (m_testParams.subsampledLoads)
1888	{
1889		const char* moduleName = "frag_update_subsampled";
1890		m_fragmentShaderModuleUpdateSubsampledImage = createShaderModule(vk, vkDevice, bc.get(moduleName), 0);
1891	}
1892	const char* moduleName = (m_testParams.viewCount > 1) ? "frag_output_2darray" : "frag_output_2d";
1893	m_fragmentShaderModuleOutputSubsampledImage = createShaderModule(vk, vkDevice, bc.get(moduleName), 0);
1894
1895	const std::vector<VkRect2D>	dynamicDensityMapRenderArea	{ makeRect2D(densityMapImageSize.width, densityMapImageSize.height) };
1896	const std::vector<VkRect2D>	outputRenderArea			{ makeRect2D(outputImageSize.width, outputImageSize.height) };
1897	const VkRect2D				colorImageRect				= makeRect2D(colorImageSize.width, colorImageSize.height);
1898	std::vector<VkRect2D>		colorImageRenderArea		((m_testParams.multiViewport ? m_testParams.viewCount : 1u), colorImageRect);
1899
1900	// Create pipelines
1901	{
1902		const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo
1903		{
1904			VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType
1905			DE_NULL,													// const void*								pNext
1906			(VkPipelineMultisampleStateCreateFlags)0u,					// VkPipelineMultisampleStateCreateFlags	flags
1907			(VkSampleCountFlagBits)m_testParams.colorSamples,			// VkSampleCountFlagBits					rasterizationSamples
1908			VK_FALSE,													// VkBool32									sampleShadingEnable
1909			1.0f,														// float									minSampleShading
1910			DE_NULL,													// const VkSampleMask*						pSampleMask
1911			VK_FALSE,													// VkBool32									alphaToCoverageEnable
1912			VK_FALSE													// VkBool32									alphaToOneEnable
1913		};
1914
1915		const std::vector<VkViewport>	viewportsProduceDynamicDensityMap	{ makeViewport(densityMapImageSize.width, densityMapImageSize.height) };
1916		const std::vector<VkViewport>	viewportsOutputSubsampledImage		{ makeViewport(outputImageSize.width, outputImageSize.height) };
1917		std::vector<VkViewport>			viewportsSubsampledImage			(colorImageRenderArea.size(), makeViewport(colorImageSize.width, colorImageSize.height));
1918
1919		// test multiview in conjunction with multiViewport which specifies a different viewport per view
1920		if (m_testParams.multiViewport)
1921		{
1922			const deUint32 halfWidth	= colorImageSize.width / 2u;
1923			const float halfWidthFloat	= static_cast<float>(halfWidth);
1924			const float halfHeightFloat	= static_cast<float>(colorImageSize.height / 2u);
1925			for (deUint32 viewIndex = 0; viewIndex < m_testParams.viewCount; ++viewIndex)
1926			{
1927				// modify scissors/viewport for every other view
1928				bool isOdd = viewIndex % 2;
1929
1930				auto& rect			= colorImageRenderArea[viewIndex];
1931				rect.extent.width	= halfWidth;
1932				rect.offset.x		= isOdd * halfWidth;
1933
1934				auto& viewport		= viewportsSubsampledImage[viewIndex];
1935				viewport.width		= halfWidthFloat;
1936				viewport.height		= halfHeightFloat;
1937				viewport.y			= !isOdd * halfHeightFloat;
1938				viewport.x			= isOdd * halfWidthFloat;
1939			}
1940		}
1941
1942		std::vector<vk::VkPipelineRenderingCreateInfoKHR> renderingCreateInfo(3,
1943		{
1944			vk::VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
1945			DE_NULL,
1946			m_viewMask,
1947			1u,
1948			&m_testParams.densityMapFormat,
1949			vk::VK_FORMAT_UNDEFINED,
1950			vk::VK_FORMAT_UNDEFINED
1951		});
1952		renderingCreateInfo[1].pColorAttachmentFormats = &colorImageFormat;
1953		renderingCreateInfo[2].viewMask = 0;
1954		renderingCreateInfo[2].pColorAttachmentFormats = &colorImageFormat;
1955
1956		const void* pNextForProduceDynamicDensityMap	= (isDynamicRendering ? &renderingCreateInfo[0] : DE_NULL);
1957		const void* pNextForeProduceSubsampledImage		= (isDynamicRendering ? &renderingCreateInfo[1] : DE_NULL);
1958		const void* pNextForeUpdateSubsampledImage		= (isDynamicRendering ? &renderingCreateInfo[1] : DE_NULL);
1959		const void* pNextForOutputSubsampledImage		= (isDynamicRendering ? &renderingCreateInfo[2] : DE_NULL);
1960
1961		if (testParams.dynamicDensityMap)
1962			m_graphicsPipelineProduceDynamicDensityMap = buildGraphicsPipeline(vk,							// const DeviceInterface&							vk
1963															vkDevice,										// const VkDevice									device
1964															*m_pipelineLayoutNoDescriptors,					// const VkPipelineLayout							pipelineLayout
1965															*m_vertexCommonShaderModule,					// const VkShaderModule								vertexShaderModule
1966															*m_fragmentShaderModuleProduceSubsampledImage,	// const VkShaderModule								fragmentShaderModule
1967															*m_renderPassProduceDynamicDensityMap,			// const VkRenderPass								renderPass
1968															viewportsProduceDynamicDensityMap,				// const std::vector<VkViewport>&					viewport
1969															dynamicDensityMapRenderArea,					// const std::vector<VkRect2D>&						scissor
1970															0u,												// const deUint32									subpass
1971															DE_NULL,										// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
1972															pNextForProduceDynamicDensityMap,				// const void*										pNext
1973															isDynamicRendering,								// const bool										useDensityMapAttachment
1974															m_testParams.useMaintenance5);					// const bool										useMaintenance5
1975
1976		m_graphicsPipelineProduceSubsampledImage = buildGraphicsPipeline(vk,								// const DeviceInterface&							vk
1977															vkDevice,										// const VkDevice									device
1978															*m_pipelineLayoutNoDescriptors,					// const VkPipelineLayout							pipelineLayout
1979															*m_vertexCommonShaderModule,					// const VkShaderModule								vertexShaderModule
1980															*m_fragmentShaderModuleProduceSubsampledImage,	// const VkShaderModule								fragmentShaderModule
1981															*m_renderPassProduceSubsampledImage,			// const VkRenderPass								renderPass
1982															viewportsSubsampledImage,						// const std::vector<VkViewport>&					viewport
1983															colorImageRenderArea,							// const std::vector<VkRect2D>&						scissor
1984															0u,												// const deUint32									subpass
1985															&multisampleStateCreateInfo,					// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
1986															pNextForeProduceSubsampledImage,				// const void*										pNext
1987															isDynamicRendering,								// const bool										useDensityMapAttachment
1988															m_testParams.useMaintenance5);					// const bool										useMaintenance5
1989
1990		if(m_testParams.makeCopy)
1991			m_graphicsPipelineCopySubsampledImage = buildGraphicsPipeline(vk,								// const DeviceInterface&							vk
1992															vkDevice,										// const VkDevice									device
1993															*m_pipelineLayoutOperateOnSubsampledImage,		// const VkPipelineLayout							pipelineLayout
1994															*m_vertexCommonShaderModule,					// const VkShaderModule								vertexShaderModule
1995															*m_fragmentShaderModuleCopySubsampledImage,		// const VkShaderModule								fragmentShaderModule
1996															*m_renderPassProduceSubsampledImage,			// const VkRenderPass								renderPass
1997															viewportsSubsampledImage,						// const std::vector<VkViewport>&					viewport
1998															colorImageRenderArea,							// const std::vector<VkRect2D>&						scissor
1999															1u,												// const deUint32									subpass
2000															&multisampleStateCreateInfo,					// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
2001															DE_NULL,										// const void*										pNext
2002															DE_FALSE);										// const bool										useDensityMapAttachment
2003		if (m_testParams.subsampledLoads)
2004			m_graphicsPipelineUpdateSubsampledImage = buildGraphicsPipeline(vk,								// const DeviceInterface&							vk
2005															vkDevice,										// const VkDevice									device
2006															*m_pipelineLayoutOperateOnSubsampledImage,		// const VkPipelineLayout							pipelineLayout
2007															*m_vertexCommonShaderModule,					// const VkShaderModule								vertexShaderModule
2008															*m_fragmentShaderModuleUpdateSubsampledImage,	// const VkShaderModule								fragmentShaderModule
2009															*m_renderPassUpdateSubsampledImage,				// const VkRenderPass								renderPass
2010															viewportsSubsampledImage,						// const std::vector<VkViewport>&					viewport
2011															colorImageRenderArea,							// const std::vector<VkRect2D>&						scissor
2012															0u,												// const deUint32									subpass
2013															&multisampleStateCreateInfo,					// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
2014															pNextForeUpdateSubsampledImage,					// const void*										pNext
2015															isDynamicRendering,								// const bool										useDensityMapAttachment
2016															m_testParams.useMaintenance5);					// const bool										useMaintenance5
2017
2018
2019		m_graphicsPipelineOutputSubsampledImage = buildGraphicsPipeline(vk,									// const DeviceInterface&							vk
2020															vkDevice,										// const VkDevice									device
2021															*m_pipelineLayoutOutputSubsampledImage,			// const VkPipelineLayout							pipelineLayout
2022															*m_vertexCommonShaderModule,					// const VkShaderModule								vertexShaderModule
2023															*m_fragmentShaderModuleOutputSubsampledImage,	// const VkShaderModule								fragmentShaderModule
2024															*m_renderPassOutputSubsampledImage,				// const VkRenderPass								renderPass
2025															viewportsOutputSubsampledImage,					// const std::vector<VkViewport>&					viewport
2026															outputRenderArea,								// const std::vector<VkRect2D>&						scissor
2027															0u,												// const deUint32									subpass
2028															DE_NULL,										// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
2029															pNextForOutputSubsampledImage,					// const void*										pNext
2030															DE_FALSE);										// const bool										useDensityMapAttachment
2031	}
2032
2033	// Create vertex buffers
2034	const tcu::Vec2 densityX(m_densityValue.x());
2035	const tcu::Vec2 densityY(m_densityValue.y());
2036	m_vertices			= createFullscreenMesh(1, {0.0f, 1.0f}, {0.0f, 1.0f});							// create fullscreen quad with gradient
2037	if (testParams.dynamicDensityMap)
2038		m_verticesDDM	= createFullscreenMesh(1, densityX, densityY);									// create fullscreen quad with single color
2039	m_verticesOutput	= createFullscreenMesh(m_testParams.viewCount, { 0.0f, 0.0f }, { 0.0f, 0.0f });	// create fullscreen mesh with black color
2040
2041	createVertexBuffer(vk, vkDevice, queueFamilyIndex, memAlloc, m_vertices, m_vertexBuffer, m_vertexBufferAlloc);
2042	if (testParams.dynamicDensityMap)
2043		createVertexBuffer(vk, vkDevice, queueFamilyIndex, memAlloc, m_verticesDDM, m_vertexBufferDDM, m_vertexBufferAllocDDM);
2044	createVertexBuffer(vk, vkDevice, queueFamilyIndex, memAlloc, m_verticesOutput, m_vertexBufferOutput, m_vertexBufferOutputAlloc);
2045
2046	// Create command pool and command buffer
2047	m_cmdPool	= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
2048	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2049
2050	if (isDynamicRendering)
2051		createCommandBufferForDynamicRendering(dynamicDensityMapRenderArea[0], colorImageRect, outputRenderArea[0], vkDevice);
2052	else
2053		createCommandBufferForRenderpass(renderPassWrapper, colorImageSize, dynamicDensityMapRenderArea[0], colorImageRect, outputRenderArea[0]);
2054}
2055
2056void FragmentDensityMapTestInstance::drawDynamicDensityMap(VkCommandBuffer cmdBuffer)
2057{
2058	const DeviceInterface&	vk					= m_context.getDeviceInterface();
2059	const VkDeviceSize		vertexBufferOffset	= 0;
2060
2061	vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelineProduceDynamicDensityMap);
2062	vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &m_vertexBufferDDM.get(), &vertexBufferOffset);
2063	vk.cmdDraw(cmdBuffer, (deUint32)m_verticesDDM.size(), 1, 0, 0);
2064}
2065
2066void FragmentDensityMapTestInstance::drawSubsampledImage(VkCommandBuffer cmdBuffer)
2067{
2068	const DeviceInterface&	vk					= m_context.getDeviceInterface();
2069	const VkDeviceSize		vertexBufferOffset	= 0;
2070
2071	vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelineProduceSubsampledImage);
2072	vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
2073	vk.cmdDraw(cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
2074}
2075
2076void FragmentDensityMapTestInstance::drawResampleSubsampledImage(VkCommandBuffer cmdBuffer)
2077{
2078	const DeviceInterface&	vk					= m_context.getDeviceInterface();
2079	const VkDeviceSize		vertexBufferOffset	= 0;
2080
2081	vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelineUpdateSubsampledImage);
2082	vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayoutOperateOnSubsampledImage, 0, 1, &m_descriptorSetOperateOnSubsampledImage.get(), 0, DE_NULL);
2083	vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
2084	vk.cmdDraw(cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
2085}
2086
2087void FragmentDensityMapTestInstance::drawCopySubsampledImage(VkCommandBuffer cmdBuffer)
2088{
2089	const DeviceInterface&	vk					= m_context.getDeviceInterface();
2090	const VkDeviceSize		vertexBufferOffset	= 0;
2091
2092	vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelineOutputSubsampledImage);
2093	vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayoutOutputSubsampledImage, 0, 1, &m_descriptorSetOutputSubsampledImage.get(), 0, DE_NULL);
2094	vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &m_vertexBufferOutput.get(), &vertexBufferOffset);
2095	vk.cmdDraw(cmdBuffer, (deUint32)m_verticesOutput.size(), 1, 0, 0);
2096}
2097
2098void FragmentDensityMapTestInstance::createCommandBufferForRenderpass(RenderPassWrapperBasePtr	renderPassWrapper,
2099																	  const VkExtent3D&			colorImageSize,
2100																	  const VkRect2D&			dynamicDensityMapRenderArea,
2101																	  const VkRect2D&			colorImageRenderArea,
2102																	  const VkRect2D&			outputRenderArea)
2103{
2104	const DeviceInterface&				vk							= m_context.getDeviceInterface();
2105	const VkDevice						vkDevice					= getDevice(m_context);
2106	const VkDeviceSize					vertexBufferOffset			= 0;
2107	const bool							isColorImageMultisampled	= m_testParams.colorSamples != VK_SAMPLE_COUNT_1_BIT;
2108	const VkClearValue					attachmentClearValue		= makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f);
2109	const deUint32						attachmentCount				= 1 + m_testParams.makeCopy + isColorImageMultisampled;
2110	const std::vector<VkClearValue>		attachmentClearValues		(attachmentCount, attachmentClearValue);
2111
2112	if (m_testParams.groupParams->useSecondaryCmdBuffer)
2113	{
2114		VkCommandBufferInheritanceInfo bufferInheritanceInfo
2115		{
2116			VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,						// VkStructureType					sType;
2117			DE_NULL,																// const void*						pNext;
2118			*m_renderPassProduceDynamicDensityMap,									// VkRenderPass						renderPass;
2119			0,																		// uint32_t							subpass;
2120			*m_framebufferProduceDynamicDensityMap,									// VkFramebuffer					framebuffer;
2121			false,																	// VkBool32							occlusionQueryEnable;
2122			0u,																		// VkQueryControlFlags				queryFlags;
2123			DE_NULL,																// VkQueryPipelineStatisticFlags	pipelineStatistics;
2124		};
2125		const VkCommandBufferBeginInfo commandBufBeginParams
2126		{
2127			VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,														// VkStructureType					sType;
2128			DE_NULL,																							// const void*						pNext;
2129			VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,		// VkCommandBufferUsageFlags		flags;
2130			&bufferInheritanceInfo
2131		};
2132
2133		if (m_testParams.dynamicDensityMap)
2134		{
2135			m_dynamicDensityMapSecCmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2136			vk.beginCommandBuffer(*m_dynamicDensityMapSecCmdBuffer, &commandBufBeginParams);
2137			drawDynamicDensityMap(*m_dynamicDensityMapSecCmdBuffer);
2138			endCommandBuffer(vk, *m_dynamicDensityMapSecCmdBuffer);
2139		}
2140
2141		bufferInheritanceInfo.renderPass = *m_renderPassProduceSubsampledImage;
2142		bufferInheritanceInfo.framebuffer = *m_framebufferProduceSubsampledImage;
2143		m_subsampledImageSecCmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2144		vk.beginCommandBuffer(*m_subsampledImageSecCmdBuffer, &commandBufBeginParams);
2145		drawSubsampledImage(*m_subsampledImageSecCmdBuffer);
2146		if (m_testParams.makeCopy)
2147		{
2148			renderPassWrapper->cmdNextSubpass(*m_subsampledImageSecCmdBuffer);
2149			vk.cmdBindPipeline(*m_subsampledImageSecCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelineCopySubsampledImage);
2150			vk.cmdBindDescriptorSets(*m_subsampledImageSecCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayoutOperateOnSubsampledImage, 0, 1, &m_descriptorSetOperateOnSubsampledImage.get(), 0, DE_NULL);
2151			vk.cmdBindVertexBuffers(*m_subsampledImageSecCmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
2152			vk.cmdDraw(*m_subsampledImageSecCmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
2153		}
2154		endCommandBuffer(vk, *m_subsampledImageSecCmdBuffer);
2155
2156		if (m_testParams.subsampledLoads)
2157		{
2158			bufferInheritanceInfo.renderPass = *m_renderPassUpdateSubsampledImage;
2159			bufferInheritanceInfo.framebuffer = *m_framebufferUpdateSubsampledImage;
2160			m_resampleSubsampledImageSecCmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2161			vk.beginCommandBuffer(*m_resampleSubsampledImageSecCmdBuffer, &commandBufBeginParams);
2162			drawResampleSubsampledImage(*m_resampleSubsampledImageSecCmdBuffer);
2163			endCommandBuffer(vk, *m_resampleSubsampledImageSecCmdBuffer);
2164		}
2165
2166		bufferInheritanceInfo.renderPass = *m_renderPassOutputSubsampledImage;
2167		bufferInheritanceInfo.framebuffer = *m_framebufferOutputSubsampledImage;
2168		m_copySubsampledImageSecCmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2169		vk.beginCommandBuffer(*m_copySubsampledImageSecCmdBuffer, &commandBufBeginParams);
2170		drawCopySubsampledImage(*m_copySubsampledImageSecCmdBuffer);
2171		endCommandBuffer(vk, *m_copySubsampledImageSecCmdBuffer);
2172	}
2173
2174	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
2175
2176	// First render pass - render dynamic density map
2177	if (m_testParams.dynamicDensityMap)
2178	{
2179		std::vector<VkClearValue>	attachmentClearValuesDDM{ makeClearValueColorF32(1.0f, 1.0f, 1.0f, 1.0f) };
2180
2181		const VkRenderPassAttachmentBeginInfo renderPassAttachmentBeginInfo
2182		{
2183			VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO,							// VkStructureType		sType;
2184			DE_NULL,																		// const void*			pNext;
2185			1u,																				// deUint32				attachmentCount;
2186			&**m_densityMapImageViews[0]													// const VkImageView*	pAttachments;
2187		};
2188
2189		const VkRenderPassBeginInfo renderPassBeginInfoProduceDynamicDensityMap
2190		{
2191			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,										// VkStructureType		sType;
2192			m_testParams.imagelessFramebuffer ? &renderPassAttachmentBeginInfo : DE_NULL,	// const void*			pNext;
2193			*m_renderPassProduceDynamicDensityMap,											// VkRenderPass			renderPass;
2194			*m_framebufferProduceDynamicDensityMap,											// VkFramebuffer		framebuffer;
2195			dynamicDensityMapRenderArea,													// VkRect2D				renderArea;
2196			static_cast<deUint32>(attachmentClearValuesDDM.size()),							// uint32_t				clearValueCount;
2197			attachmentClearValuesDDM.data()													// const VkClearValue*	pClearValues;
2198		};
2199
2200		renderPassWrapper->cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfoProduceDynamicDensityMap);
2201
2202		if (m_testParams.groupParams->useSecondaryCmdBuffer)
2203			vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_dynamicDensityMapSecCmdBuffer);
2204		else
2205			drawDynamicDensityMap(*m_cmdBuffer);
2206
2207		renderPassWrapper->cmdEndRenderPass(*m_cmdBuffer);
2208	}
2209
2210	// Render subsampled image
2211	{
2212		std::vector<VkImageView> imageViewsProduceSubsampledImage = { *m_colorImageView };
2213		if (isColorImageMultisampled)
2214			imageViewsProduceSubsampledImage.push_back(*m_colorResolvedImageView);
2215		if (m_testParams.makeCopy)
2216			imageViewsProduceSubsampledImage.push_back(*m_colorCopyImageView);
2217		imageViewsProduceSubsampledImage.push_back(**m_densityMapImageViews[0]);
2218
2219		const VkRenderPassAttachmentBeginInfo renderPassAttachmentBeginInfo
2220		{
2221			VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO,								// VkStructureType		sType;
2222			DE_NULL,																			// const void*			pNext;
2223			static_cast<deUint32>(imageViewsProduceSubsampledImage.size()),						// deUint32				attachmentCount;
2224			imageViewsProduceSubsampledImage.data()												// const VkImageView*	pAttachments;
2225		};
2226
2227		const VkRenderPassBeginInfo renderPassBeginInfoProduceSubsampledImage
2228		{
2229			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,											// VkStructureType		sType;
2230			m_testParams.imagelessFramebuffer ? &renderPassAttachmentBeginInfo : DE_NULL,		// const void*			pNext;
2231			*m_renderPassProduceSubsampledImage,												// VkRenderPass			renderPass;
2232			*m_framebufferProduceSubsampledImage,												// VkFramebuffer		framebuffer;
2233			colorImageRenderArea,																// VkRect2D				renderArea;
2234			static_cast<deUint32>(attachmentClearValues.size()),								// uint32_t				clearValueCount;
2235			attachmentClearValues.data()														// const VkClearValue*	pClearValues;
2236		};
2237		renderPassWrapper->cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfoProduceSubsampledImage);
2238
2239		if (m_testParams.groupParams->useSecondaryCmdBuffer)
2240			vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_subsampledImageSecCmdBuffer);
2241		else
2242		{
2243			drawSubsampledImage(*m_cmdBuffer);
2244			if (m_testParams.makeCopy)
2245			{
2246				renderPassWrapper->cmdNextSubpass(*m_cmdBuffer);
2247				vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelineCopySubsampledImage);
2248				vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayoutOperateOnSubsampledImage, 0, 1, &m_descriptorSetOperateOnSubsampledImage.get(), 0, DE_NULL);
2249				vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
2250				vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
2251			}
2252		}
2253
2254		renderPassWrapper->cmdEndRenderPass(*m_cmdBuffer);
2255	}
2256
2257	// Resample subsampled image
2258	if (m_testParams.subsampledLoads)
2259	{
2260		VkImageView pAttachments[] = { *m_colorImageView, **m_densityMapImageViews[1] };
2261		const VkRenderPassAttachmentBeginInfo renderPassAttachmentBeginInfo
2262		{
2263			VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO,							// VkStructureType		sType;
2264			DE_NULL,																		// const void*			pNext;
2265			2u,																				// deUint32				attachmentCount;
2266			pAttachments																	// const VkImageView*	pAttachments;
2267		};
2268
2269		const VkRenderPassBeginInfo renderPassBeginInfoUpdateSubsampledImage
2270		{
2271			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,										// VkStructureType		sType;
2272			m_testParams.imagelessFramebuffer ? &renderPassAttachmentBeginInfo : DE_NULL,	// const void*			pNext;
2273			*m_renderPassUpdateSubsampledImage,												// VkRenderPass			renderPass;
2274			*m_framebufferUpdateSubsampledImage,											// VkFramebuffer		framebuffer;
2275			makeRect2D(colorImageSize.width, colorImageSize.height),						// VkRect2D				renderArea;
2276			0u,																				// uint32_t				clearValueCount;
2277			DE_NULL																			// const VkClearValue*	pClearValues;
2278		};
2279		renderPassWrapper->cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfoUpdateSubsampledImage);
2280
2281		if (m_testParams.groupParams->useSecondaryCmdBuffer)
2282			vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_resampleSubsampledImageSecCmdBuffer);
2283		else
2284			drawResampleSubsampledImage(*m_cmdBuffer);
2285
2286		renderPassWrapper->cmdEndRenderPass(*m_cmdBuffer);
2287	}
2288
2289	// Copy subsampled image to normal image using sampler that is able to read from subsampled images
2290	// (subsampled image cannot be copied using vkCmdCopyImageToBuffer)
2291	const VkRenderPassAttachmentBeginInfo renderPassAttachmentBeginInfo
2292	{
2293		VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO,								// VkStructureType		sType;
2294		DE_NULL,																			// const void*			pNext;
2295		1u,																					// deUint32				attachmentCount;
2296		&*m_outputImageView																	// const VkImageView*	pAttachments;
2297	};
2298
2299	const VkRenderPassBeginInfo renderPassBeginInfoOutputSubsampledImage
2300	{
2301		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,											// VkStructureType		sType;
2302		m_testParams.imagelessFramebuffer ? &renderPassAttachmentBeginInfo : DE_NULL,		// const void*			pNext;
2303		*m_renderPassOutputSubsampledImage,													// VkRenderPass			renderPass;
2304		*m_framebufferOutputSubsampledImage,												// VkFramebuffer		framebuffer;
2305		outputRenderArea,																	// VkRect2D				renderArea;
2306		static_cast<deUint32>(attachmentClearValues.size()),								// uint32_t				clearValueCount;
2307		attachmentClearValues.data()														// const VkClearValue*	pClearValues;
2308	};
2309	renderPassWrapper->cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfoOutputSubsampledImage);
2310
2311	if (m_testParams.groupParams->useSecondaryCmdBuffer)
2312		vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_copySubsampledImageSecCmdBuffer);
2313	else
2314		drawCopySubsampledImage(*m_cmdBuffer);
2315
2316	renderPassWrapper->cmdEndRenderPass(*m_cmdBuffer);
2317
2318	endCommandBuffer(vk, *m_cmdBuffer);
2319}
2320
2321void FragmentDensityMapTestInstance::createCommandBufferForDynamicRendering(const VkRect2D&		dynamicDensityMapRenderArea,
2322																			const VkRect2D&		colorImageRenderArea,
2323																			const VkRect2D&		outputRenderArea,
2324																			const VkDevice&     vkDevice)
2325{
2326	// no subpasses in dynamic rendering - makeCopy tests are not repeated for dynamic rendering
2327	DE_ASSERT (!m_testParams.makeCopy);
2328
2329	const DeviceInterface&				vk							= m_context.getDeviceInterface();
2330	const bool							isColorImageMultisampled	= m_testParams.colorSamples != VK_SAMPLE_COUNT_1_BIT;
2331	std::vector<VkClearValue>			attachmentClearValuesDDM	{ makeClearValueColorF32(1.0f, 1.0f, 1.0f, 1.0f) };
2332	const VkClearValue					attachmentClearValue		= makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f);
2333	const deUint32						attachmentCount				= 1 + m_testParams.makeCopy + isColorImageMultisampled;
2334	const std::vector<VkClearValue>		attachmentClearValues		(attachmentCount, attachmentClearValue);
2335	const VkImageSubresourceRange		dynamicDensitMapSubresourceRange	{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, m_testParams.viewCount, 0u, 1u };
2336	const VkImageSubresourceRange		colorSubresourceRange				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_testParams.viewCount };
2337	const VkImageSubresourceRange		outputSubresourceRange				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u };
2338
2339	const VkImageMemoryBarrier dynamicDensitMapBarrier = makeImageMemoryBarrier(
2340		m_testParams.useMemoryAccess ? VK_ACCESS_MEMORY_READ_BIT
2341									 : VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT,		// VkAccessFlags			srcAccessMask;
2342		m_testParams.useMemoryAccess ? VK_ACCESS_MEMORY_WRITE_BIT
2343									 : VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
2344		VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT,								// VkImageLayout			oldLayout;
2345		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,										// VkImageLayout			newLayout;
2346		**m_densityMapImages[0],														// VkImage					image;
2347		dynamicDensitMapSubresourceRange												// VkImageSubresourceRange	subresourceRange;
2348	);
2349
2350	const VkImageMemoryBarrier densityMapImageBarrier = makeImageMemoryBarrier(
2351		m_testParams.useMemoryAccess ? VK_ACCESS_MEMORY_WRITE_BIT
2352									 : VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			srcAccessMask;
2353		m_testParams.useMemoryAccess ? VK_ACCESS_MEMORY_READ_BIT
2354									 : VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT,		// VkAccessFlags			dstAccessMask;
2355		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,										// VkImageLayout			oldLayout;
2356		VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT,								// VkImageLayout			newLayout;
2357		**m_densityMapImages[0],														// VkImage					image;
2358		colorSubresourceRange															// VkImageSubresourceRange	subresourceRange;
2359	);
2360
2361	std::vector<VkImageMemoryBarrier> cbImageBarrier(2, makeImageMemoryBarrier(
2362		VK_ACCESS_NONE_KHR,																// VkAccessFlags			srcAccessMask;
2363		m_testParams.useMemoryAccess ? VK_ACCESS_MEMORY_WRITE_BIT
2364									 : VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
2365		VK_IMAGE_LAYOUT_UNDEFINED,														// VkImageLayout			oldLayout;
2366		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,										// VkImageLayout			newLayout;
2367		*m_colorImage,																	// VkImage					image;
2368		colorSubresourceRange															// VkImageSubresourceRange	subresourceRange;
2369	));
2370	cbImageBarrier[1].image = *m_colorResolvedImage;
2371
2372	const VkImageMemoryBarrier subsampledImageBarrier = makeImageMemoryBarrier(
2373		m_testParams.useMemoryAccess ? VK_ACCESS_MEMORY_WRITE_BIT
2374									 : VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags						srcAccessMask;
2375		m_testParams.useMemoryAccess ? VK_ACCESS_MEMORY_READ_BIT
2376									 : VK_ACCESS_SHADER_READ_BIT,						// VkAccessFlags						dstAccessMask;
2377		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,										// VkImageLayout						oldLayout;
2378		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,										// VkImageLayout						newLayout;
2379		*m_colorImage,																	// VkImage								image;
2380		colorSubresourceRange															// VkImageSubresourceRange				subresourceRange;
2381	);
2382
2383	const VkImageMemoryBarrier outputImageBarrier = makeImageMemoryBarrier(
2384		VK_ACCESS_NONE_KHR,																// VkAccessFlags						srcAccessMask;
2385		m_testParams.useMemoryAccess ? VK_ACCESS_MEMORY_WRITE_BIT
2386									 : VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags						dstAccessMask;
2387		VK_IMAGE_LAYOUT_UNDEFINED,														// VkImageLayout						oldLayout;
2388		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,										// VkImageLayout						newLayout;
2389		*m_outputImage,																	// VkImage								image;
2390		outputSubresourceRange															// VkImageSubresourceRange				subresourceRange;
2391	);
2392
2393	const VkRenderingFragmentDensityMapAttachmentInfoEXT densityMap0Attachment
2394	{
2395		VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_INFO_EXT,			// VkStructureType						sType;
2396		DE_NULL,																		// const void*							pNext;
2397		**m_densityMapImageViews[0],													// VkImageView							imageView;
2398		VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT								// VkImageLayout						imageLayout;
2399	};
2400
2401	const VkRenderingFragmentDensityMapAttachmentInfoEXT densityMap1Attachment
2402	{
2403		VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_INFO_EXT,			// VkStructureType						sType;
2404		DE_NULL,																		// const void*							pNext;
2405		m_testParams.subsampledLoads ? **m_densityMapImageViews[1] : DE_NULL,			// VkImageView							imageView;
2406		VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT								// VkImageLayout						imageLayout;
2407	};
2408
2409	const VkRenderingAttachmentInfoKHR dynamicDensityMapColorAttachment
2410	{
2411		VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,								// VkStructureType						sType;
2412		DE_NULL,																		// const void*							pNext;
2413		**m_densityMapImageViews[0],													// VkImageView							imageView;
2414		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,										// VkImageLayout						imageLayout;
2415		VK_RESOLVE_MODE_NONE,															// VkResolveModeFlagBits				resolveMode;
2416		DE_NULL,																		// VkImageView							resolveImageView;
2417		VK_IMAGE_LAYOUT_UNDEFINED,														// VkImageLayout						resolveImageLayout;
2418		VK_ATTACHMENT_LOAD_OP_CLEAR,													// VkAttachmentLoadOp					loadOp;
2419		VK_ATTACHMENT_STORE_OP_STORE,													// VkAttachmentStoreOp					storeOp;
2420		attachmentClearValuesDDM[0]														// VkClearValue							clearValue;
2421	};
2422
2423	VkRenderingInfoKHR dynamicDensityMapRenderingInfo
2424	{
2425		VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
2426		DE_NULL,
2427		0u,																				// VkRenderingFlagsKHR					flags;
2428		dynamicDensityMapRenderArea,													// VkRect2D								renderArea;
2429		m_testParams.viewCount,															// deUint32								layerCount;
2430		m_viewMask,																		// deUint32								viewMask;
2431		1u,																				// deUint32								colorAttachmentCount;
2432		&dynamicDensityMapColorAttachment,												// const VkRenderingAttachmentInfoKHR*	pColorAttachments;
2433		DE_NULL,																		// const VkRenderingAttachmentInfoKHR*	pDepthAttachment;
2434		DE_NULL,																		// const VkRenderingAttachmentInfoKHR*	pStencilAttachment;
2435	};
2436
2437	const VkRenderingAttachmentInfoKHR subsampledImageColorAttachment
2438	{
2439		VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,								// VkStructureType						sType;
2440		DE_NULL,																		// const void*							pNext;
2441		*m_colorImageView,																// VkImageView							imageView;
2442		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,										// VkImageLayout						imageLayout;
2443		isColorImageMultisampled ? VK_RESOLVE_MODE_AVERAGE_BIT : VK_RESOLVE_MODE_NONE,	// VkResolveModeFlagBits				resolveMode;
2444		isColorImageMultisampled ? *m_colorResolvedImageView : DE_NULL,					// VkImageView							resolveImageView;
2445		isColorImageMultisampled ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
2446									: VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout						resolveImageLayout;
2447		VK_ATTACHMENT_LOAD_OP_CLEAR,													// VkAttachmentLoadOp					loadOp;
2448		VK_ATTACHMENT_STORE_OP_STORE,													// VkAttachmentStoreOp					storeOp;
2449		attachmentClearValues[0]														// VkClearValue							clearValue;
2450	};
2451
2452	VkRenderingInfoKHR subsampledImageRenderingInfo
2453	{
2454		VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
2455		&densityMap0Attachment,
2456		0u,																				// VkRenderingFlagsKHR					flags;
2457		colorImageRenderArea,															// VkRect2D								renderArea;
2458		m_testParams.viewCount,															// deUint32								layerCount;
2459		m_viewMask,																		// deUint32								viewMask;
2460		1u,																				// deUint32								colorAttachmentCount;
2461		&subsampledImageColorAttachment,												// const VkRenderingAttachmentInfoKHR*	pColorAttachments;
2462		DE_NULL,																		// const VkRenderingAttachmentInfoKHR*	pDepthAttachment;
2463		DE_NULL,																		// const VkRenderingAttachmentInfoKHR*	pStencilAttachment;
2464	};
2465
2466	const VkRenderingAttachmentInfoKHR resampleSubsampledImageColorAttachment
2467	{
2468		VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,								// VkStructureType						sType;
2469		DE_NULL,																		// const void*							pNext;
2470		*m_colorImageView,																// VkImageView							imageView;
2471		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,										// VkImageLayout						imageLayout;
2472		VK_RESOLVE_MODE_NONE,															// VkResolveModeFlagBits				resolveMode;
2473		DE_NULL,																		// VkImageView							resolveImageView;
2474		VK_IMAGE_LAYOUT_UNDEFINED,														// VkImageLayout						resolveImageLayout;
2475		VK_ATTACHMENT_LOAD_OP_LOAD,														// VkAttachmentLoadOp					loadOp;
2476		VK_ATTACHMENT_STORE_OP_STORE,													// VkAttachmentStoreOp					storeOp;
2477		attachmentClearValues[0]														// VkClearValue							clearValue;
2478	};
2479
2480	VkRenderingInfoKHR resampleSubsampledImageRenderingInfo
2481	{
2482		VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
2483		&densityMap1Attachment,
2484		0u,																				// VkRenderingFlagsKHR					flags;
2485		colorImageRenderArea,															// VkRect2D								renderArea;
2486		m_testParams.viewCount,															// deUint32								layerCount;
2487		m_viewMask,																		// deUint32								viewMask;
2488		1u,																				// deUint32								colorAttachmentCount;
2489		&resampleSubsampledImageColorAttachment,										// const VkRenderingAttachmentInfoKHR*	pColorAttachments;
2490		DE_NULL,																		// const VkRenderingAttachmentInfoKHR*	pDepthAttachment;
2491		DE_NULL,																		// const VkRenderingAttachmentInfoKHR*	pStencilAttachment;
2492	};
2493
2494	const VkRenderingAttachmentInfoKHR copySubsampledColorAttachment
2495	{
2496		VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,								// VkStructureType						sType;
2497		DE_NULL,																		// const void*							pNext;
2498		*m_outputImageView,																// VkImageView							imageView;
2499		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,										// VkImageLayout						imageLayout;
2500		VK_RESOLVE_MODE_NONE,															// VkResolveModeFlagBits				resolveMode;
2501		DE_NULL,																		// VkImageView							resolveImageView;
2502		VK_IMAGE_LAYOUT_UNDEFINED,														// VkImageLayout						resolveImageLayout;
2503		VK_ATTACHMENT_LOAD_OP_CLEAR,													// VkAttachmentLoadOp					loadOp;
2504		VK_ATTACHMENT_STORE_OP_STORE,													// VkAttachmentStoreOp					storeOp;
2505		attachmentClearValues[0]														// VkClearValue							clearValue;
2506	};
2507
2508	VkRenderingInfoKHR copySubsampledRenderingInfo
2509	{
2510		VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
2511		DE_NULL,
2512		0u,																				// VkRenderingFlagsKHR					flags;
2513		outputRenderArea,																// VkRect2D								renderArea;
2514		1u,																				// deUint32								layerCount;
2515		0u,																				// deUint32								viewMask;
2516		1u,																				// deUint32								colorAttachmentCount;
2517		&copySubsampledColorAttachment,													// const VkRenderingAttachmentInfoKHR*	pColorAttachments;
2518		DE_NULL,																		// const VkRenderingAttachmentInfoKHR*	pDepthAttachment;
2519		DE_NULL,																		// const VkRenderingAttachmentInfoKHR*	pStencilAttachment;
2520	};
2521
2522	if (m_testParams.groupParams->useSecondaryCmdBuffer)
2523	{
2524		const VkFormat colorImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
2525		VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo
2526		{
2527			VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR,			// VkStructureType						sType;
2528			DE_NULL,																	// const void*							pNext;
2529			0u,																			// VkRenderingFlagsKHR					flags;
2530			m_viewMask,																	// uint32_t								viewMask;
2531			1u,																			// uint32_t								colorAttachmentCount;
2532			&m_testParams.densityMapFormat,												// const VkFormat*						pColorAttachmentFormats;
2533			VK_FORMAT_UNDEFINED,														// VkFormat								depthAttachmentFormat;
2534			VK_FORMAT_UNDEFINED,														// VkFormat								stencilAttachmentFormat;
2535			VK_SAMPLE_COUNT_1_BIT														// VkSampleCountFlagBits				rasterizationSamples;
2536		};
2537
2538		const VkCommandBufferInheritanceInfo	bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo);
2539		VkCommandBufferBeginInfo				commandBufBeginParams
2540		{
2541			VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,							// VkStructureType					sType;
2542			DE_NULL,																// const void*						pNext;
2543			VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,							// VkCommandBufferUsageFlags		flags;
2544			&bufferInheritanceInfo
2545		};
2546
2547		m_dynamicDensityMapSecCmdBuffer			= allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2548		m_subsampledImageSecCmdBuffer			= allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2549		m_resampleSubsampledImageSecCmdBuffer	= allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2550		m_copySubsampledImageSecCmdBuffer		= allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2551
2552		// Record secondary command buffers
2553		if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2554		{
2555			inheritanceRenderingInfo.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT;
2556
2557			if (m_testParams.dynamicDensityMap)
2558			{
2559				vk.beginCommandBuffer(*m_dynamicDensityMapSecCmdBuffer, &commandBufBeginParams);
2560				vk.cmdBeginRendering(*m_dynamicDensityMapSecCmdBuffer, &dynamicDensityMapRenderingInfo);
2561				drawDynamicDensityMap(*m_dynamicDensityMapSecCmdBuffer);
2562				vk.cmdEndRendering(*m_dynamicDensityMapSecCmdBuffer);
2563				endCommandBuffer(vk, *m_dynamicDensityMapSecCmdBuffer);
2564			}
2565
2566			inheritanceRenderingInfo.pColorAttachmentFormats	= &colorImageFormat;
2567			inheritanceRenderingInfo.rasterizationSamples		= m_testParams.colorSamples;
2568			vk.beginCommandBuffer(*m_subsampledImageSecCmdBuffer, &commandBufBeginParams);
2569			vk.cmdBeginRendering(*m_subsampledImageSecCmdBuffer, &subsampledImageRenderingInfo);
2570			drawSubsampledImage(*m_subsampledImageSecCmdBuffer);
2571			vk.cmdEndRendering(*m_subsampledImageSecCmdBuffer);
2572			endCommandBuffer(vk, *m_subsampledImageSecCmdBuffer);
2573
2574			if (m_testParams.subsampledLoads)
2575			{
2576				vk.beginCommandBuffer(*m_resampleSubsampledImageSecCmdBuffer, &commandBufBeginParams);
2577				vk.cmdBeginRendering(*m_resampleSubsampledImageSecCmdBuffer, &resampleSubsampledImageRenderingInfo);
2578				drawResampleSubsampledImage(*m_resampleSubsampledImageSecCmdBuffer);
2579				vk.cmdEndRendering(*m_resampleSubsampledImageSecCmdBuffer);
2580				endCommandBuffer(vk, *m_resampleSubsampledImageSecCmdBuffer);
2581			}
2582
2583			inheritanceRenderingInfo.viewMask				= 0u;
2584			inheritanceRenderingInfo.rasterizationSamples	= VK_SAMPLE_COUNT_1_BIT;
2585			vk.beginCommandBuffer(*m_copySubsampledImageSecCmdBuffer, &commandBufBeginParams);
2586			vk.cmdBeginRendering(*m_copySubsampledImageSecCmdBuffer, &copySubsampledRenderingInfo);
2587			drawCopySubsampledImage(*m_copySubsampledImageSecCmdBuffer);
2588			vk.cmdEndRendering(*m_copySubsampledImageSecCmdBuffer);
2589			endCommandBuffer(vk, *m_copySubsampledImageSecCmdBuffer);
2590		}
2591		else
2592		{
2593			commandBufBeginParams.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
2594
2595			if (m_testParams.dynamicDensityMap)
2596			{
2597				vk.beginCommandBuffer(*m_dynamicDensityMapSecCmdBuffer, &commandBufBeginParams);
2598				drawDynamicDensityMap(*m_dynamicDensityMapSecCmdBuffer);
2599				endCommandBuffer(vk, *m_dynamicDensityMapSecCmdBuffer);
2600			}
2601
2602			inheritanceRenderingInfo.pColorAttachmentFormats	= &colorImageFormat;
2603			inheritanceRenderingInfo.rasterizationSamples		= m_testParams.colorSamples;
2604			vk.beginCommandBuffer(*m_subsampledImageSecCmdBuffer, &commandBufBeginParams);
2605			drawSubsampledImage(*m_subsampledImageSecCmdBuffer);
2606			endCommandBuffer(vk, *m_subsampledImageSecCmdBuffer);
2607
2608			if (m_testParams.subsampledLoads)
2609			{
2610				vk.beginCommandBuffer(*m_resampleSubsampledImageSecCmdBuffer, &commandBufBeginParams);
2611				drawResampleSubsampledImage(*m_resampleSubsampledImageSecCmdBuffer);
2612				endCommandBuffer(vk, *m_resampleSubsampledImageSecCmdBuffer);
2613			}
2614
2615			inheritanceRenderingInfo.viewMask				= 0u;
2616			inheritanceRenderingInfo.rasterizationSamples	= VK_SAMPLE_COUNT_1_BIT;
2617			vk.beginCommandBuffer(*m_copySubsampledImageSecCmdBuffer, &commandBufBeginParams);
2618			drawCopySubsampledImage(*m_copySubsampledImageSecCmdBuffer);
2619			endCommandBuffer(vk, *m_copySubsampledImageSecCmdBuffer);
2620		}
2621
2622		// Record primary command buffer
2623		beginCommandBuffer(vk, *m_cmdBuffer, 0u);
2624
2625		// Render dynamic density map
2626		if (m_testParams.dynamicDensityMap)
2627		{
2628			// change layout of density map - after filling it layout was changed
2629			// to density map optimal but here we want to render values to it
2630			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_NONE_KHR, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2631				0, 0, DE_NULL, 0, DE_NULL, 1, &dynamicDensitMapBarrier);
2632
2633			if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2634				vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_dynamicDensityMapSecCmdBuffer);
2635			else
2636			{
2637				dynamicDensityMapRenderingInfo.flags = vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
2638				vk.cmdBeginRendering(*m_cmdBuffer, &dynamicDensityMapRenderingInfo);
2639				vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_dynamicDensityMapSecCmdBuffer);
2640				vk.cmdEndRendering(*m_cmdBuffer);
2641			}
2642
2643			// barrier that will change layout of density map
2644			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT,
2645				0, 0, DE_NULL, 0, DE_NULL, 1, &densityMapImageBarrier);
2646		}
2647
2648		// barrier that will change layout of color and resolve attachments
2649		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_NONE_KHR, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2650			0, 0, DE_NULL, 0, DE_NULL, 1 + isColorImageMultisampled, cbImageBarrier.data());
2651
2652		// Render subsampled image
2653		if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2654			vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_subsampledImageSecCmdBuffer);
2655		else
2656		{
2657			subsampledImageRenderingInfo.flags = vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
2658			vk.cmdBeginRendering(*m_cmdBuffer, &subsampledImageRenderingInfo);
2659			vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_subsampledImageSecCmdBuffer);
2660			vk.cmdEndRendering(*m_cmdBuffer);
2661		}
2662
2663		// Resample subsampled image
2664		if (m_testParams.subsampledLoads)
2665		{
2666			if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2667				vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_resampleSubsampledImageSecCmdBuffer);
2668			else
2669			{
2670				resampleSubsampledImageRenderingInfo.flags = vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
2671				vk.cmdBeginRendering(*m_cmdBuffer, &resampleSubsampledImageRenderingInfo);
2672				vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_resampleSubsampledImageSecCmdBuffer);
2673				vk.cmdEndRendering(*m_cmdBuffer);
2674			}
2675		}
2676
2677		// barrier that ensures writing to colour image has completed.
2678		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2679							  0, 0, DE_NULL, 0, DE_NULL, 1u, &subsampledImageBarrier);
2680
2681		// barrier that will change layout of output image
2682		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_NONE_KHR, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2683			0, 0, DE_NULL, 0, DE_NULL, 1, &outputImageBarrier);
2684
2685		if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2686			vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_copySubsampledImageSecCmdBuffer);
2687		else
2688		{
2689			copySubsampledRenderingInfo.flags = vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
2690			vk.cmdBeginRendering(*m_cmdBuffer, &copySubsampledRenderingInfo);
2691			vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_copySubsampledImageSecCmdBuffer);
2692			vk.cmdEndRendering(*m_cmdBuffer);
2693		}
2694
2695		endCommandBuffer(vk, *m_cmdBuffer);
2696	}
2697	else
2698	{
2699		beginCommandBuffer(vk, *m_cmdBuffer, 0u);
2700
2701		// First render pass - render dynamic density map
2702		if (m_testParams.dynamicDensityMap)
2703		{
2704			// change layout of density map - after filling it layout was changed
2705			// to density map optimal but here we want to render values to it
2706			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_NONE_KHR, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2707								  0, 0, DE_NULL, 0, DE_NULL, 1, &dynamicDensitMapBarrier);
2708
2709			vk.cmdBeginRendering(*m_cmdBuffer, &dynamicDensityMapRenderingInfo);
2710			drawDynamicDensityMap(*m_cmdBuffer);
2711			vk.cmdEndRendering(*m_cmdBuffer);
2712
2713			// barrier that will change layout of density map
2714			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT,
2715								  0, 0, DE_NULL, 0, DE_NULL, 1, &densityMapImageBarrier);
2716		}
2717
2718		// barrier that will change layout of color and resolve attachments
2719		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_NONE_KHR, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2720							  0, 0, DE_NULL, 0, DE_NULL, 1 + isColorImageMultisampled, cbImageBarrier.data());
2721
2722		// Render subsampled image
2723		vk.cmdBeginRendering(*m_cmdBuffer, &subsampledImageRenderingInfo);
2724		drawSubsampledImage(*m_cmdBuffer);
2725		vk.cmdEndRendering(*m_cmdBuffer);
2726
2727		// Resample subsampled image
2728		if (m_testParams.subsampledLoads)
2729		{
2730			vk.cmdBeginRendering(*m_cmdBuffer, &resampleSubsampledImageRenderingInfo);
2731			drawResampleSubsampledImage(*m_cmdBuffer);
2732			vk.cmdEndRendering(*m_cmdBuffer);
2733		}
2734
2735		// barrier that ensures writing to colour image has completed.
2736		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
2737							  0, 0, DE_NULL, 0, DE_NULL, 1u, &subsampledImageBarrier);
2738
2739		// barrier that will change layout of output image
2740		vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_NONE_KHR, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2741							  0, 0, DE_NULL, 0, DE_NULL, 1, &outputImageBarrier);
2742
2743		vk.cmdBeginRendering(*m_cmdBuffer, &copySubsampledRenderingInfo);
2744		drawCopySubsampledImage(*m_cmdBuffer);
2745		vk.cmdEndRendering(*m_cmdBuffer);
2746
2747		endCommandBuffer(vk, *m_cmdBuffer);
2748	}
2749}
2750
2751tcu::TestStatus FragmentDensityMapTestInstance::iterate (void)
2752{
2753	const DeviceInterface&	vk			= m_context.getDeviceInterface();
2754	const VkDevice			vkDevice	= getDevice(m_context);
2755	const VkQueue			queue		= getDeviceQueue(vk, vkDevice, m_context.getUniversalQueueFamilyIndex(), 0);
2756
2757	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
2758
2759	// approximations used when coarse reconstruction is specified are implementation defined
2760	if (m_testParams.coarseReconstruction)
2761		return tcu::TestStatus::pass("Pass");
2762
2763	return verifyImage();
2764}
2765
2766struct Vec4Sorter
2767{
2768	bool operator()(const tcu::Vec4& lhs, const tcu::Vec4& rhs) const
2769	{
2770		if (lhs.x() != rhs.x())
2771			return lhs.x() < rhs.x();
2772		if (lhs.y() != rhs.y())
2773			return lhs.y() < rhs.y();
2774		if (lhs.z() != rhs.z())
2775			return lhs.z() < rhs.z();
2776		return lhs.w() < rhs.w();
2777	}
2778};
2779
2780tcu::TestStatus FragmentDensityMapTestInstance::verifyImage (void)
2781{
2782	const DeviceInterface&				vk					= m_context.getDeviceInterface();
2783	const VkDevice						vkDevice			= getDevice(m_context);
2784	const deUint32						queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
2785	const VkQueue						queue				= getDeviceQueue(vk, vkDevice, queueFamilyIndex, 0);
2786	SimpleAllocator						memAlloc			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
2787	tcu::UVec2							renderSize			(m_renderSize.x(), m_renderSize.y());
2788	de::UniquePtr<tcu::TextureLevel>	outputImage			(pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, memAlloc, *m_outputImage, VK_FORMAT_R8G8B8A8_UNORM, renderSize).release());
2789	const tcu::ConstPixelBufferAccess&	outputAccess		(outputImage->getAccess());
2790	tcu::TestLog&						log					(m_context.getTestContext().getLog());
2791
2792	// Log images
2793	log << tcu::TestLog::ImageSet("Result", "Result images")
2794		<< tcu::TestLog::Image("Rendered", "Rendered output image", outputAccess)
2795		<< tcu::TestLog::EndImageSet;
2796
2797	deInt32		noColorCount		= 0;
2798	deUint32	estimatedColorCount	= m_testParams.viewCount * m_testParams.fragmentArea.x() * m_testParams.fragmentArea.y();
2799	float		densityMult			= m_densityValue.x() * m_densityValue.y();
2800
2801	// Create histogram of all image colors, check the value of inverted FragSizeEXT
2802	std::map<tcu::Vec4, deUint32, Vec4Sorter> colorCount;
2803	for (int y = 0; y < outputAccess.getHeight(); y++)
2804	{
2805		for (int x = 0; x < outputAccess.getWidth(); x++)
2806		{
2807			tcu::Vec4	outputColor		= outputAccess.getPixel(x, y);
2808			float		densityClamped	= outputColor.z() * outputColor.w();
2809
2810			// for multiviewport cases we check only pixels to which we render
2811			if (m_testParams.multiViewport && outputColor.x() < 0.01f)
2812			{
2813				++noColorCount;
2814				continue;
2815			}
2816
2817			if ((densityClamped + 0.01) < densityMult)
2818				return tcu::TestStatus::fail("Wrong value of FragSizeEXT variable");
2819
2820			auto it = colorCount.find(outputColor);
2821			if (it == end(colorCount))
2822				it = colorCount.insert({ outputColor, 0u }).first;
2823			it->second++;
2824		}
2825	}
2826
2827	// Check if color count is the same as estimated one
2828	for (const auto& color : colorCount)
2829	{
2830		if (color.second > estimatedColorCount)
2831			return tcu::TestStatus::fail("Wrong color count");
2832	}
2833
2834	// For multiviewport cases ~75% of fragments should be black;
2835	// The margin of 100 fragments is used to compensate cases where
2836	// we can't fit all views in a same way to final 64x64 image
2837	// (64 can't be evenly divide for 6 views)
2838	deInt32 estimatedNoColorCount = m_renderSize.x() * m_renderSize.y() * 3 / 4;
2839	if (m_testParams.multiViewport && std::abs(noColorCount - estimatedNoColorCount) > 100)
2840		return tcu::TestStatus::fail("Wrong number of fragments with black color");
2841
2842	return tcu::TestStatus::pass("Pass");
2843}
2844
2845} // anonymous
2846
2847static void createChildren (tcu::TestCaseGroup* fdmTests, const SharedGroupParams groupParams)
2848{
2849	tcu::TestContext&	testCtx		= fdmTests->getTestContext();
2850
2851	const struct
2852	{
2853		std::string		name;
2854		deUint32		viewCount;
2855	} views[] =
2856	{
2857		{ "1_view",		1 },
2858		{ "2_views",	2 },
2859		{ "4_views",	4 },
2860		{ "6_views",	6 },
2861	};
2862
2863	const struct
2864	{
2865		std::string			name;
2866		bool				makeCopy;
2867	} renders[] =
2868	{
2869		{ "render",			false },
2870		{ "render_copy",	true }
2871	};
2872
2873	const struct
2874	{
2875		std::string		name;
2876		float			renderSizeToDensitySize;
2877	} sizes[] =
2878	{
2879		{ "divisible_density_size",		4.0f },
2880		{ "non_divisible_density_size",	3.75f }
2881	};
2882
2883	const struct
2884	{
2885		std::string				name;
2886		VkSampleCountFlagBits	samples;
2887	} samples[] =
2888	{
2889		{ "1_sample",	VK_SAMPLE_COUNT_1_BIT },
2890		{ "2_samples",	VK_SAMPLE_COUNT_2_BIT },
2891		{ "4_samples",	VK_SAMPLE_COUNT_4_BIT },
2892		{ "8_samples",	VK_SAMPLE_COUNT_8_BIT }
2893	};
2894
2895	std::vector<tcu::UVec2> fragmentArea
2896	{
2897		{ 1, 2 },
2898		{ 2, 1 },
2899		{ 2, 2 }
2900	};
2901
2902	for (const auto& view : views)
2903	{
2904		if ((groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY) && view.viewCount > 1)
2905			continue;
2906
2907		de::MovePtr<tcu::TestCaseGroup> viewGroup(new tcu::TestCaseGroup(testCtx, view.name.c_str()));
2908		for (const auto& render : renders)
2909		{
2910			if ((groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING) && render.makeCopy)
2911				continue;
2912
2913			de::MovePtr<tcu::TestCaseGroup> renderGroup(new tcu::TestCaseGroup(testCtx, render.name.c_str()));
2914			for (const auto& size : sizes)
2915			{
2916				de::MovePtr<tcu::TestCaseGroup> sizeGroup(new tcu::TestCaseGroup(testCtx, size.name.c_str()));
2917				for (const auto& sample : samples)
2918				{
2919					// Reduce number of tests for dynamic rendering cases where secondary command buffer is used
2920					if (groupParams->useSecondaryCmdBuffer && (sample.samples > VK_SAMPLE_COUNT_2_BIT))
2921						break;
2922
2923					de::MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup(testCtx, sample.name.c_str()));
2924					for (const auto& area : fragmentArea)
2925					{
2926						std::stringstream str;
2927						str << "_" << area.x() << "_" << area.y();
2928
2929						TestParams params
2930						{
2931							false,							// bool						dynamicDensityMap;
2932							false,							// bool						deferredDensityMap;
2933							false,							// bool						nonSubsampledImages;
2934							false,							// bool						subsampledLoads;
2935							false,							// bool						coarseReconstruction;
2936							false,							// bool						imagelessFramebuffer;
2937							false,							// bool						useMemoryAccess;
2938							false,							// bool						useMaintenance5;
2939							1,								// deUint32					samplersCount;
2940							view.viewCount,					// deUint32					viewCount;
2941							false,							// bool						multiViewport;
2942							render.makeCopy,				// bool						makeCopy;
2943							size.renderSizeToDensitySize,	// float					renderMultiplier;
2944							sample.samples,					// VkSampleCountFlagBits	colorSamples;
2945							area,							// tcu::UVec2				fragmentArea;
2946							{ 16, 16 },						// tcu::UVec2				densityMapSize;
2947							VK_FORMAT_R8G8_UNORM,			// VkFormat					densityMapFormat;
2948							groupParams						// SharedGroupParams		groupParams;
2949						};
2950
2951						sampleGroup->addChild(new FragmentDensityMapTest(testCtx, std::string("static_subsampled") + str.str(), params));
2952						params.deferredDensityMap	= true;
2953						sampleGroup->addChild(new FragmentDensityMapTest(testCtx, std::string("deferred_subsampled") + str.str(), params));
2954						params.deferredDensityMap	= false;
2955						params.dynamicDensityMap	= true;
2956						sampleGroup->addChild(new FragmentDensityMapTest(testCtx, std::string("dynamic_subsampled") + str.str(), params));
2957
2958						// generate nonsubsampled tests just for single view and double view cases
2959						if (view.viewCount < 3)
2960						{
2961							params.nonSubsampledImages	= true;
2962							params.dynamicDensityMap	= false;
2963							sampleGroup->addChild(new FragmentDensityMapTest(testCtx, std::string("static_nonsubsampled") + str.str(), params));
2964							params.deferredDensityMap	= true;
2965							sampleGroup->addChild(new FragmentDensityMapTest(testCtx, std::string("deferred_nonsubsampled") + str.str(), params));
2966							params.deferredDensityMap	= false;
2967							params.dynamicDensityMap	= true;
2968							sampleGroup->addChild(new FragmentDensityMapTest(testCtx, std::string("dynamic_nonsubsampled") + str.str(), params));
2969						}
2970
2971						// test multiviewport - each of views uses different viewport; limit number of cases to 2 samples
2972						if ((groupParams->renderingType == RENDERING_TYPE_RENDERPASS2) && (!render.makeCopy) &&
2973							(view.viewCount > 1) && (sample.samples == VK_SAMPLE_COUNT_2_BIT))
2974						{
2975							params.nonSubsampledImages	= false;
2976							params.dynamicDensityMap	= false;
2977							params.deferredDensityMap	= false;
2978							params.multiViewport		= true;
2979							sampleGroup->addChild(new FragmentDensityMapTest(testCtx, std::string("static_subsampled") + str.str() + "_multiviewport", params));
2980						}
2981					}
2982					sizeGroup->addChild(sampleGroup.release());
2983				}
2984				renderGroup->addChild(sizeGroup.release());
2985			}
2986			viewGroup->addChild(renderGroup.release());
2987		}
2988		fdmTests->addChild(viewGroup.release());
2989	}
2990
2991	const struct
2992	{
2993		std::string		name;
2994		deUint32		count;
2995	} subsampledSamplers[] =
2996	{
2997		{ "2_subsampled_samplers",	2 },
2998		{ "4_subsampled_samplers",	4 },
2999		{ "6_subsampled_samplers",	6 },
3000		{ "8_subsampled_samplers",	8 }
3001	};
3002
3003	de::MovePtr<tcu::TestCaseGroup> propertiesGroup(new tcu::TestCaseGroup(testCtx, "properties"));
3004	for (const auto& sampler : subsampledSamplers)
3005	{
3006		TestParams params
3007		{
3008			false,							// bool						dynamicDensityMap;
3009			false,							// bool						deferredDensityMap;
3010			false,							// bool						nonSubsampledImages;
3011			false,							// bool						subsampledLoads;
3012			false,							// bool						coarseReconstruction;
3013			false,							// bool						imagelessFramebuffer;
3014			false,							// bool						useMemoryAccess;
3015			false,							// bool						useMaintenance5;
3016			sampler.count,					// deUint32					samplersCount;
3017			1,								// deUint32					viewCount;
3018			false,							// bool						multiViewport;
3019			false,							// bool						makeCopy;
3020			4.0f,							// float					renderMultiplier;
3021			VK_SAMPLE_COUNT_1_BIT,			// VkSampleCountFlagBits	colorSamples;
3022			{  2,  2 },						// tcu::UVec2				fragmentArea;
3023			{ 16, 16 },						// tcu::UVec2				densityMapSize;
3024			VK_FORMAT_R8G8_UNORM,			// VkFormat					densityMapFormat;
3025			groupParams						// SharedGroupParams		groupParams;
3026		};
3027		propertiesGroup->addChild(new FragmentDensityMapTest(testCtx, sampler.name, params));
3028
3029		// Reduce number of tests for dynamic rendering cases where secondary command buffer is used
3030		if (groupParams->useSecondaryCmdBuffer)
3031			break;
3032	}
3033
3034	if ((groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING) && (groupParams->useSecondaryCmdBuffer == false))
3035	{
3036		TestParams params
3037		{
3038			false,							// bool						dynamicDensityMap;
3039			false,							// bool						deferredDensityMap;
3040			false,							// bool						nonSubsampledImages;
3041			false,							// bool						subsampledLoads;
3042			false,							// bool						coarseReconstruction;
3043			false,							// bool						imagelessFramebuffer;
3044			false,							// bool						useMemoryAccess;
3045			true,							// bool						useMaintenance5;
3046			1,								// deUint32					samplersCount;
3047			1,								// deUint32					viewCount;
3048			false,							// bool						multiViewport;
3049			false,							// bool						makeCopy;
3050			4.0f,							// float					renderMultiplier;
3051			VK_SAMPLE_COUNT_1_BIT,			// VkSampleCountFlagBits	colorSamples;
3052			{  2,  2 },						// tcu::UVec2				fragmentArea;
3053			{ 16, 16 },						// tcu::UVec2				densityMapSize;
3054			VK_FORMAT_R8G8_UNORM,			// VkFormat					densityMapFormat;
3055			groupParams						// SharedGroupParams		groupParams;
3056		};
3057		propertiesGroup->addChild(new FragmentDensityMapTest(testCtx, "maintenance5", params));
3058	}
3059
3060	if (groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
3061	{
3062		// interaction between fragment density map and imageless framebuffer
3063
3064		const struct
3065		{
3066			std::string		name;
3067			bool			useSecondaryCmdBuffer;
3068		} commandBufferType[] =
3069		{
3070			{ "",						false},
3071			{ "secondary_cmd_buff_",	true}
3072		};
3073
3074		for (const auto& cmdBuffType : commandBufferType)
3075		{
3076			TestParams params
3077			{
3078				false,									// bool						dynamicDensityMap;
3079				false,									// bool						deferredDensityMap;
3080				false,									// bool						nonSubsampledImages;
3081				false,									// bool						subsampledLoads;
3082				false,									// bool						coarseReconstruction;
3083				true,									// bool						imagelessFramebuffer;
3084				false,									// bool						useMemoryAccess;
3085				false,									// bool						useMaintenance5;
3086				1,										// deUint32					samplersCount;
3087				1,										// deUint32					viewCount;
3088				false,									// bool						multiViewport;
3089				false,									// bool						makeCopy;
3090				4.0f,									// float					renderMultiplier;
3091				VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	colorSamples;
3092				{  2,  2 },								// tcu::UVec2				fragmentArea;
3093				{ 16, 16 },								// tcu::UVec2				densityMapSize;
3094				VK_FORMAT_R8G8_UNORM,					// VkFormat					densityMapFormat;
3095				SharedGroupParams(new GroupParams		// SharedGroupParams		groupParams;
3096				{
3097					groupParams->renderingType,			//		RenderingType		renderingType;
3098					cmdBuffType.useSecondaryCmdBuffer,	//		bool				useSecondaryCmdBuffer;
3099					false,								//		bool				secondaryCmdBufferCompletelyContainsDynamicRenderpass;
3100				})
3101			};
3102			std::string namePrefix = cmdBuffType.name;
3103
3104			params.deferredDensityMap = false;
3105			params.dynamicDensityMap = false;
3106			propertiesGroup->addChild(new FragmentDensityMapTest(testCtx, namePrefix + "imageless_framebuffer_static_subsampled", params));
3107			params.deferredDensityMap = true;
3108			propertiesGroup->addChild(new FragmentDensityMapTest(testCtx, namePrefix + "imageless_framebuffer_deferred_subsampled", params));
3109			params.deferredDensityMap = false;
3110			params.dynamicDensityMap = true;
3111			propertiesGroup->addChild(new FragmentDensityMapTest(testCtx, namePrefix + "imageless_framebuffer_dynamic_subsampled", params));
3112		}
3113	}
3114
3115	if (groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
3116	{
3117		TestParams params
3118		{
3119			false,							// bool						dynamicDensityMap;
3120			false,							// bool						deferredDensityMap;
3121			false,							// bool						nonSubsampledImages;
3122			true,							// bool						subsampledLoads;
3123			false,							// bool						coarseReconstruction;
3124			false,							// bool						imagelessFramebuffer;
3125			false,							// bool						useMemoryAccess;
3126			false,							// bool						useMaintenance5;
3127			1,								// deUint32					samplersCount;
3128			2,								// deUint32					viewCount;
3129			false,							// bool						multiViewport;
3130			false,							// bool						makeCopy;
3131			4.0f,							// float					renderMultiplier;
3132			VK_SAMPLE_COUNT_1_BIT,			// VkSampleCountFlagBits	colorSamples;
3133			{  1,  2 },						// tcu::UVec2				fragmentArea;
3134			{ 16, 16 },						// tcu::UVec2				densityMapSize;
3135			VK_FORMAT_R8G8_UNORM,			// VkFormat					densityMapFormat;
3136			groupParams						// SharedGroupParams		groupParams;
3137		};
3138		propertiesGroup->addChild(new FragmentDensityMapTest(testCtx, "subsampled_loads", params));
3139		params.subsampledLoads		= false;
3140		params.coarseReconstruction	= true;
3141		propertiesGroup->addChild(new FragmentDensityMapTest(testCtx, "subsampled_coarse_reconstruction", params));
3142		params.useMemoryAccess		= true;
3143		propertiesGroup->addChild(new FragmentDensityMapTest(testCtx, "memory_access", params));
3144	}
3145
3146	fdmTests->addChild(propertiesGroup.release());
3147}
3148
3149static void cleanupGroup (tcu::TestCaseGroup* group, const SharedGroupParams)
3150{
3151	DE_UNREF(group);
3152	// Destroy singleton objects.
3153	g_singletonDevice.clear();
3154}
3155
3156tcu::TestCaseGroup* createFragmentDensityMapTests (tcu::TestContext& testCtx, const SharedGroupParams groupParams)
3157{
3158	// VK_EXT_fragment_density_map and VK_EXT_fragment_density_map2 extensions tests
3159	return createTestGroup(testCtx, "fragment_density_map", createChildren, groupParams, cleanupGroup);
3160}
3161
3162} // renderpass
3163
3164} // vkt
3165