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