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