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