• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 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 Buffer and image memory requirements tests.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktMemoryRequirementsTests.hpp"
25 #include "vktTestCaseUtil.hpp"
26 #include "vktTestGroupUtil.hpp"
27 
28 #include "vkDefs.hpp"
29 #include "vkRef.hpp"
30 #include "vkRefUtil.hpp"
31 #include "vkMemUtil.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkStrUtil.hpp"
34 #include "vkTypeUtil.hpp"
35 #include "vkImageUtil.hpp"
36 
37 #include "deUniquePtr.hpp"
38 #include "deStringUtil.hpp"
39 #include "deSTLUtil.hpp"
40 
41 #include "tcuResultCollector.hpp"
42 #include "tcuTestLog.hpp"
43 
44 #include <set>
45 
46 namespace vkt
47 {
48 namespace memory
49 {
50 namespace
51 {
52 using namespace vk;
53 using de::MovePtr;
54 using tcu::TestLog;
55 
makeBuffer(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize size,const VkBufferCreateFlags flags,const VkBufferUsageFlags usage)56 Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags, const VkBufferUsageFlags usage)
57 {
58 	const VkBufferCreateInfo createInfo =
59 	{
60 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType        sType;
61 		DE_NULL,									// const void*            pNext;
62 		flags,										// VkBufferCreateFlags    flags;
63 		size,										// VkDeviceSize           size;
64 		usage,										// VkBufferUsageFlags     usage;
65 		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode          sharingMode;
66 		0u,											// uint32_t               queueFamilyIndexCount;
67 		DE_NULL,									// const uint32_t*        pQueueFamilyIndices;
68 	};
69 	return createBuffer(vk, device, &createInfo);
70 }
71 
getBufferMemoryRequirements(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize size,const VkBufferCreateFlags flags,const VkBufferUsageFlags usage)72 VkMemoryRequirements getBufferMemoryRequirements (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags, const VkBufferUsageFlags usage)
73 {
74 	const Unique<VkBuffer> buffer(makeBuffer(vk, device, size, flags, usage));
75 	return getBufferMemoryRequirements(vk, device, *buffer);
76 }
77 
getBufferMemoryRequirements2(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize size,const VkBufferCreateFlags flags,const VkBufferUsageFlags usage,void * next=DE_NULL)78 VkMemoryRequirements getBufferMemoryRequirements2 (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags, const VkBufferUsageFlags usage, void* next = DE_NULL)
79 {
80 	const Unique<VkBuffer>				buffer		(makeBuffer(vk, device, size, flags, usage));
81 	VkBufferMemoryRequirementsInfo2		info	=
82 	{
83 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,		// VkStructureType	sType
84 		DE_NULL,													// const void*		pNext
85 		*buffer														// VkBuffer			buffer
86 	};
87 	VkMemoryRequirements2				req2	=
88 	{
89 		VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,					// VkStructureType		sType
90 		next,														// void*				pNext
91 		{0, 0, 0}													// VkMemoryRequirements	memoryRequirements
92 	};
93 
94 	vk.getBufferMemoryRequirements2(device, &info, &req2);
95 
96 	return req2.memoryRequirements;
97 }
98 
99 #ifndef CTS_USES_VULKANSC
getBufferCreateInfoMemoryRequirementsKHR(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize size,const VkBufferCreateFlags flags,const VkBufferUsageFlags usage,void * next=DE_NULL)100 VkMemoryRequirements getBufferCreateInfoMemoryRequirementsKHR (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags, const VkBufferUsageFlags usage, void* next = DE_NULL)
101 {
102 	const VkBufferCreateInfo createInfo =
103 	{
104 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType        sType;
105 		DE_NULL,									// const void*            pNext;
106 		flags,										// VkBufferCreateFlags    flags;
107 		size,										// VkDeviceSize           size;
108 		usage,										// VkBufferUsageFlags     usage;
109 		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode          sharingMode;
110 		0u,											// uint32_t               queueFamilyIndexCount;
111 		DE_NULL,									// const uint32_t*        pQueueFamilyIndices;
112 	};
113 	const VkDeviceBufferMemoryRequirementsKHR memoryInfo =
114 	{
115 		VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR,
116 		DE_NULL,
117 		&createInfo
118 	};
119 	VkMemoryRequirements2				req2	=
120 	{
121 		VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR,				// VkStructureType		sType
122 		next,														// void*				pNext
123 		{0, 0, 0}													// VkMemoryRequirements	memoryRequirements
124 	};
125 
126 	vk.getDeviceBufferMemoryRequirements(device, &memoryInfo, &req2);
127 
128 	return req2.memoryRequirements;
129 }
130 #endif // CTS_USES_VULKANSC
131 
getImageMemoryRequirements2(const DeviceInterface & vk,const VkDevice device,const VkImageCreateInfo & createInfo,void * next=DE_NULL)132 VkMemoryRequirements getImageMemoryRequirements2 (const DeviceInterface& vk, const VkDevice device, const VkImageCreateInfo& createInfo, void* next = DE_NULL)
133 {
134 	const Unique<VkImage> image(createImage(vk, device, &createInfo));
135 
136 	VkImageMemoryRequirementsInfo2		info	=
137 	{
138 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,			// VkStructureType	sType
139 		DE_NULL,													// const void*		pNext
140 		*image														// VkImage			image
141 	};
142 	VkMemoryRequirements2				req2	=
143 	{
144 		VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,					// VkStructureType		sType
145 		next,														// void*				pNext
146 		{0, 0, 0}													// VkMemoryRequirements	memoryRequirements
147 	};
148 
149 	vk.getImageMemoryRequirements2(device, &info, &req2);
150 
151 	return req2.memoryRequirements;
152 }
153 
154 #ifndef CTS_USES_VULKANSC
getDeviceImageMemoryRequirements(const DeviceInterface & vk,const VkDevice device,const VkImageCreateInfo & createInfo,void * next=DE_NULL)155 VkMemoryRequirements getDeviceImageMemoryRequirements (const DeviceInterface& vk, const VkDevice device, const VkImageCreateInfo& createInfo, void* next = DE_NULL)
156 {
157 	VkDeviceImageMemoryRequirementsKHR info =
158 	{
159 		VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR,
160 		DE_NULL,
161 		&createInfo,
162 		VkImageAspectFlagBits(0)
163 	};
164 	VkMemoryRequirements2				req2	=
165 	{
166 		VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR,				// VkStructureType		sType
167 		next,														// void*				pNext
168 		{0, 0, 0}													// VkMemoryRequirements	memoryRequirements
169 	};
170 
171 	vk.getDeviceImageMemoryRequirements(device, &info, &req2);
172 
173 	return req2.memoryRequirements;
174 }
175 #endif // CTS_USES_VULKANSC
176 
177 #ifndef CTS_USES_VULKANSC
getImageCreateInfoSparseMemoryRequirements(const DeviceInterface & vk,VkDevice device,const VkImageCreateInfo & createInfo)178 std::vector<VkSparseImageMemoryRequirements> getImageCreateInfoSparseMemoryRequirements (const DeviceInterface& vk, VkDevice device, const VkImageCreateInfo& createInfo)
179 {
180 	VkDeviceImageMemoryRequirementsKHR info =
181 	{
182 		VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR,
183 		DE_NULL,
184 		&createInfo,
185 		VkImageAspectFlagBits(0)
186 	};
187 	deUint32										requirementsCount = 0;
188 	std::vector<VkSparseImageMemoryRequirements>	requirements;
189 	std::vector<VkSparseImageMemoryRequirements2>	requirements2;
190 
191 	vk.getDeviceImageSparseMemoryRequirements(device, &info, &requirementsCount, DE_NULL);
192 
193 	if (requirementsCount > 0)
194 	{
195 		requirements2.resize(requirementsCount);
196 		for (deUint32 ndx = 0; ndx < requirementsCount; ++ndx)
197 		{
198 			requirements2[ndx].sType = VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2;
199 			requirements2[ndx].pNext = DE_NULL;
200 		}
201 
202 		vk.getDeviceImageSparseMemoryRequirements(device, &info, &requirementsCount, &requirements2[0]);
203 
204 		if ((size_t)requirementsCount != requirements2.size())
205 			TCU_FAIL("Returned sparse image memory requirements count changes between queries");
206 
207 		requirements.resize(requirementsCount);
208 		for (deUint32 ndx = 0; ndx < requirementsCount; ++ndx)
209 			requirements[ndx] = requirements2[ndx].memoryRequirements;
210 	}
211 
212 	return requirements;
213 }
214 #endif // CTS_USES_VULKANSC
215 
216 //! Get an index of each set bit, starting from the least significant bit.
bitsToIndices(deUint32 bits)217 std::vector<deUint32> bitsToIndices (deUint32 bits)
218 {
219 	std::vector<deUint32> indices;
220 	for (deUint32 i = 0u; bits != 0u; ++i, bits >>= 1)
221 	{
222 		if (bits & 1u)
223 			indices.push_back(i);
224 	}
225 	return indices;
226 }
227 
228 template<typename T>
nextEnum(T value)229 T nextEnum (T value)
230 {
231 	return static_cast<T>(static_cast<deUint32>(value) + 1);
232 }
233 
234 template<typename T>
nextFlag(T value)235 T nextFlag (T value)
236 {
237 	if (value)
238 		return static_cast<T>(static_cast<deUint32>(value) << 1);
239 	else
240 		return static_cast<T>(1);
241 }
242 
243 template<typename T>
nextFlagExcluding(T value,T excludedFlags)244 T nextFlagExcluding (T value, T excludedFlags)
245 {
246 	deUint32 tmp = static_cast<deUint32>(value);
247 	while ((tmp = nextFlag(tmp)) & static_cast<deUint32>(excludedFlags));
248 	return static_cast<T>(tmp);
249 }
250 
validValueVkBool32(const VkBool32 value)251 bool validValueVkBool32 (const VkBool32 value)
252 {
253 	return (value == VK_FALSE || value == VK_TRUE);
254 }
255 
256 class IBufferMemoryRequirements
257 {
258 public:
259 	virtual void populateTestGroup			(tcu::TestCaseGroup*						group) = 0;
260 
261 protected:
262 	virtual void addFunctionTestCase		(tcu::TestCaseGroup*						group,
263 											 const std::string&							name,
264 											 VkBufferCreateFlags						arg0) = 0;
265 
266 	virtual tcu::TestStatus execTest		(Context&									context,
267 											 const VkBufferCreateFlags					bufferFlags) = 0;
268 
269 	virtual void updateMemoryRequirements	(const DeviceInterface&						vk,
270 											 const VkDevice								device,
271 											 const VkDeviceSize							size,
272 											 const VkBufferCreateFlags					flags,
273 											 const VkBufferUsageFlags					usage,
274 											 const bool									all) = 0;
275 
276 	virtual void verifyMemoryRequirements	(tcu::ResultCollector&						result,
277 											 const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties,
278 											 const VkPhysicalDeviceLimits&				limits,
279 											 const VkBufferCreateFlags					bufferFlags,
280 											 const VkBufferUsageFlags					usage) = 0;
281 };
282 
283 class BufferMemoryRequirementsOriginal : public IBufferMemoryRequirements
284 {
285 	static tcu::TestStatus testEntryPoint	(Context&									context,
286 											 const VkBufferCreateFlags					bufferFlags);
287 
288 public:
289 	virtual void populateTestGroup			(tcu::TestCaseGroup*						group);
290 
291 protected:
292 	virtual void addFunctionTestCase		(tcu::TestCaseGroup*						group,
293 											 const std::string&							name,
294 											 VkBufferCreateFlags						arg0);
295 
296 	virtual tcu::TestStatus execTest		(Context&									context,
297 											 const VkBufferCreateFlags					bufferFlags);
298 
299 	virtual void updateMemoryRequirements	(const DeviceInterface&						vk,
300 											 const VkDevice								device,
301 											 const VkDeviceSize							size,
302 											 const VkBufferCreateFlags					flags,
303 											 const VkBufferUsageFlags					usage,
304 											 const bool									all);
305 
306 	virtual void verifyMemoryRequirements	(tcu::ResultCollector&						result,
307 											 const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties,
308 											 const VkPhysicalDeviceLimits&				limits,
309 											 const VkBufferCreateFlags					bufferFlags,
310 											 const VkBufferUsageFlags					usage);
311 
312 protected:
313 	VkMemoryRequirements	m_allUsageFlagsRequirements;
314 	VkMemoryRequirements	m_currentTestRequirements;
315 };
316 
317 
testEntryPoint(Context & context,const VkBufferCreateFlags bufferFlags)318 tcu::TestStatus BufferMemoryRequirementsOriginal::testEntryPoint (Context& context, const VkBufferCreateFlags bufferFlags)
319 {
320 	BufferMemoryRequirementsOriginal test;
321 
322 	return test.execTest(context, bufferFlags);
323 }
324 
populateTestGroup(tcu::TestCaseGroup * group)325 void BufferMemoryRequirementsOriginal::populateTestGroup (tcu::TestCaseGroup* group)
326 {
327 	const struct
328 	{
329 		VkBufferCreateFlags		flags;
330 		const char* const		name;
331 	} bufferCases[] =
332 	{
333 		{ (VkBufferCreateFlags)0,																								"regular"					},
334 #ifndef CTS_USES_VULKANSC
335 		{ VK_BUFFER_CREATE_SPARSE_BINDING_BIT,																					"sparse"					},
336 		{ VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,											"sparse_residency"			},
337 		{ VK_BUFFER_CREATE_SPARSE_BINDING_BIT											| VK_BUFFER_CREATE_SPARSE_ALIASED_BIT,	"sparse_aliased"			},
338 		{ VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT	| VK_BUFFER_CREATE_SPARSE_ALIASED_BIT,	"sparse_residency_aliased"	},
339 #endif // CTS_USES_VULKANSC
340 	};
341 
342 	de::MovePtr<tcu::TestCaseGroup> bufferGroup(new tcu::TestCaseGroup(group->getTestContext(), "buffer"));
343 
344 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(bufferCases); ++ndx)
345 		addFunctionTestCase(bufferGroup.get(), bufferCases[ndx].name, bufferCases[ndx].flags);
346 
347 	group->addChild(bufferGroup.release());
348 }
349 
checkSupportBufferMemoryRequirementsOriginal(Context & context,VkBufferCreateFlags flags)350 void checkSupportBufferMemoryRequirementsOriginal (Context& context, VkBufferCreateFlags flags)
351 {
352 	if (flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT)
353 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_BINDING);
354 
355 	if (flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT)
356 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_BUFFER);
357 
358 	if (flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT)
359 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_ALIASED);
360 }
361 
addFunctionTestCase(tcu::TestCaseGroup * group,const std::string & name,VkBufferCreateFlags arg0)362 void BufferMemoryRequirementsOriginal::addFunctionTestCase (tcu::TestCaseGroup*	group,
363 															const std::string&	name,
364 															VkBufferCreateFlags	arg0)
365 {
366 	addFunctionCase(group, name, checkSupportBufferMemoryRequirementsOriginal, testEntryPoint, arg0);
367 }
368 
execTest(Context & context,const VkBufferCreateFlags bufferFlags)369 tcu::TestStatus BufferMemoryRequirementsOriginal::execTest (Context& context, const VkBufferCreateFlags bufferFlags)
370 {
371 	const DeviceInterface&					vk			= context.getDeviceInterface();
372 	const InstanceInterface&				vki			= context.getInstanceInterface();
373 	const VkDevice							device		= context.getDevice();
374 	const VkPhysicalDevice					physDevice	= context.getPhysicalDevice();
375 
376 	const VkPhysicalDeviceMemoryProperties	memoryProperties	= getPhysicalDeviceMemoryProperties(vki, physDevice);
377 	const VkPhysicalDeviceLimits			limits				= getPhysicalDeviceProperties(vki, physDevice).limits;
378 	const VkBufferUsageFlags				allUsageFlags		= static_cast<VkBufferUsageFlags>((VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT << 1) - 1);
379 	tcu::TestLog&							log					= context.getTestContext().getLog();
380 	bool									allPass				= true;
381 
382 	const VkDeviceSize sizeCases[] =
383 	{
384 		1    * 1024,
385 		8    * 1024,
386 		64   * 1024,
387 		1024 * 1024,
388 	};
389 
390 	// Updates m_allUsageFlags* fields
391 	updateMemoryRequirements(vk, device, 1024, bufferFlags, allUsageFlags, true); // doesn't depend on size
392 
393 	for (VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; usage <= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; usage = nextFlag(usage))
394 	{
395 		deUint32		previousMemoryTypeBits	= 0u;
396 		VkDeviceSize	previousAlignment		= 0u;
397 
398 		log << tcu::TestLog::Message << "Verify a buffer with usage flags: " << de::toString(getBufferUsageFlagsStr(usage)) << tcu::TestLog::EndMessage;
399 
400 		for (const VkDeviceSize* pSize = sizeCases; pSize < sizeCases + DE_LENGTH_OF_ARRAY(sizeCases); ++pSize)
401 		{
402 			log << tcu::TestLog::Message << "- size " << *pSize << " bytes" << tcu::TestLog::EndMessage;
403 
404 			tcu::ResultCollector result(log, "ERROR: ");
405 
406 			// Updates m_allUsageFlags* fields
407 			updateMemoryRequirements(vk, device, *pSize, bufferFlags, usage, false);
408 
409 			// Check:
410 			// - requirements for a particular buffer usage
411 			// - memoryTypeBits are a subset of bits for requirements with all usage flags combined
412 			verifyMemoryRequirements(result, memoryProperties, limits, bufferFlags, usage);
413 
414 			// Check that for the same usage and create flags:
415 			// - memoryTypeBits are the same
416 			// - alignment is the same
417 			if (pSize > sizeCases)
418 			{
419 				result.check(m_currentTestRequirements.memoryTypeBits == previousMemoryTypeBits,
420 					"memoryTypeBits differ from the ones in the previous buffer size");
421 
422 				result.check(m_currentTestRequirements.alignment == previousAlignment,
423 					"alignment differs from the one in the previous buffer size");
424 			}
425 
426 			if (result.getResult() != QP_TEST_RESULT_PASS)
427 				allPass = false;
428 
429 			previousMemoryTypeBits	= m_currentTestRequirements.memoryTypeBits;
430 			previousAlignment		= m_currentTestRequirements.alignment;
431 		}
432 
433 		if (!allPass)
434 			break;
435 	}
436 
437 	return allPass ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Some memory requirements were incorrect");
438 }
439 
updateMemoryRequirements(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize size,const VkBufferCreateFlags flags,const VkBufferUsageFlags usage,const bool all)440 void BufferMemoryRequirementsOriginal::updateMemoryRequirements (const DeviceInterface&		vk,
441 																 const VkDevice				device,
442 																 const VkDeviceSize			size,
443 																 const VkBufferCreateFlags	flags,
444 																 const VkBufferUsageFlags	usage,
445 																 const bool					all)
446 {
447 	if (all)
448 	{
449 		m_allUsageFlagsRequirements	= getBufferMemoryRequirements(vk, device, size, flags, usage);
450 	}
451 	else
452 	{
453 		m_currentTestRequirements	= getBufferMemoryRequirements(vk, device, size, flags, usage);
454 	}
455 }
456 
verifyMemoryRequirements(tcu::ResultCollector & result,const VkPhysicalDeviceMemoryProperties & deviceMemoryProperties,const VkPhysicalDeviceLimits & limits,const VkBufferCreateFlags bufferFlags,const VkBufferUsageFlags usage)457 void BufferMemoryRequirementsOriginal::verifyMemoryRequirements (tcu::ResultCollector&						result,
458 																 const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties,
459 																 const VkPhysicalDeviceLimits&				limits,
460 																 const VkBufferCreateFlags					bufferFlags,
461 																 const VkBufferUsageFlags					usage)
462 {
463 	if (result.check(m_currentTestRequirements.memoryTypeBits != 0, "VkMemoryRequirements memoryTypeBits has no bits set"))
464 	{
465 		typedef std::vector<deUint32>::const_iterator	IndexIterator;
466 		const std::vector<deUint32>						usedMemoryTypeIndices			= bitsToIndices(m_currentTestRequirements.memoryTypeBits);
467 		bool											deviceLocalMemoryFound			= false;
468 		bool											hostVisibleCoherentMemoryFound	= false;
469 
470 		for (IndexIterator memoryTypeNdx = usedMemoryTypeIndices.begin(); memoryTypeNdx != usedMemoryTypeIndices.end(); ++memoryTypeNdx)
471 		{
472 			if (*memoryTypeNdx >= deviceMemoryProperties.memoryTypeCount)
473 			{
474 				result.fail("VkMemoryRequirements memoryTypeBits contains bits for non-existing memory types");
475 				continue;
476 			}
477 
478 			const VkMemoryPropertyFlags	memoryPropertyFlags = deviceMemoryProperties.memoryTypes[*memoryTypeNdx].propertyFlags;
479 
480 			if (memoryPropertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
481 				deviceLocalMemoryFound = true;
482 
483 			if (memoryPropertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
484 				hostVisibleCoherentMemoryFound = true;
485 
486 			result.check((memoryPropertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) == 0u,
487 				"Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT");
488 		}
489 
490 		result.check(deIsPowerOfTwo64(static_cast<deUint64>(m_currentTestRequirements.alignment)) == DE_TRUE,
491 			"VkMemoryRequirements alignment isn't power of two");
492 
493 		if (usage & (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT))
494 		{
495 			result.check(m_currentTestRequirements.alignment >= limits.minTexelBufferOffsetAlignment,
496 				"VkMemoryRequirements alignment doesn't respect minTexelBufferOffsetAlignment");
497 		}
498 
499 		if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)
500 		{
501 			result.check(m_currentTestRequirements.alignment >= limits.minUniformBufferOffsetAlignment,
502 				"VkMemoryRequirements alignment doesn't respect minUniformBufferOffsetAlignment");
503 		}
504 
505 		if (usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
506 		{
507 			result.check(m_currentTestRequirements.alignment >= limits.minStorageBufferOffsetAlignment,
508 				"VkMemoryRequirements alignment doesn't respect minStorageBufferOffsetAlignment");
509 		}
510 
511 		result.check(deviceLocalMemoryFound,
512 			"None of the required memory types included VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT");
513 
514 		result.check((bufferFlags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) || hostVisibleCoherentMemoryFound,
515 			"Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and VK_MEMORY_PROPERTY_HOST_COHERENT_BIT");
516 
517 		result.check((m_currentTestRequirements.memoryTypeBits & m_allUsageFlagsRequirements.memoryTypeBits) == m_allUsageFlagsRequirements.memoryTypeBits,
518 			"Memory type bits aren't a superset of memory type bits for all usage flags combined");
519 	}
520 }
521 
522 class BufferMemoryRequirementsExtended : public BufferMemoryRequirementsOriginal
523 {
524 	static tcu::TestStatus testEntryPoint	(Context&					context,
525 											 const VkBufferCreateFlags	bufferFlags);
526 
527 protected:
528 	virtual void addFunctionTestCase		(tcu::TestCaseGroup*		group,
529 											 const std::string&			name,
530 											 VkBufferCreateFlags		arg0);
531 
532 	virtual void updateMemoryRequirements	(const DeviceInterface&		vk,
533 											 const VkDevice				device,
534 											 const VkDeviceSize			size,
535 											 const VkBufferCreateFlags	flags,
536 											 const VkBufferUsageFlags	usage,
537 											 const bool					all);
538 };
539 
testEntryPoint(Context & context,const VkBufferCreateFlags bufferFlags)540 tcu::TestStatus BufferMemoryRequirementsExtended::testEntryPoint (Context& context, const VkBufferCreateFlags bufferFlags)
541 {
542 	BufferMemoryRequirementsExtended test;
543 
544 	return test.execTest(context, bufferFlags);
545 }
546 
checkSupportBufferMemoryRequirementsExtended(Context & context,VkBufferCreateFlags flags)547 void checkSupportBufferMemoryRequirementsExtended (Context& context, VkBufferCreateFlags flags)
548 {
549 	checkSupportBufferMemoryRequirementsOriginal(context, flags);
550 
551 	context.requireDeviceFunctionality("VK_KHR_get_memory_requirements2");
552 }
553 
addFunctionTestCase(tcu::TestCaseGroup * group,const std::string & name,VkBufferCreateFlags arg0)554 void BufferMemoryRequirementsExtended::addFunctionTestCase (tcu::TestCaseGroup*	group,
555 															const std::string&	name,
556 															VkBufferCreateFlags	arg0)
557 {
558 	addFunctionCase(group, name, checkSupportBufferMemoryRequirementsExtended, testEntryPoint, arg0);
559 }
560 
updateMemoryRequirements(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize size,const VkBufferCreateFlags flags,const VkBufferUsageFlags usage,const bool all)561 void BufferMemoryRequirementsExtended::updateMemoryRequirements (const DeviceInterface&		vk,
562 																 const VkDevice				device,
563 																 const VkDeviceSize			size,
564 																 const VkBufferCreateFlags	flags,
565 																 const VkBufferUsageFlags	usage,
566 																 const bool					all)
567 {
568 	if (all)
569 	{
570 		m_allUsageFlagsRequirements	= getBufferMemoryRequirements2(vk, device, size, flags, usage);
571 	}
572 	else
573 	{
574 		m_currentTestRequirements	= getBufferMemoryRequirements2(vk, device, size, flags, usage);
575 	}
576 }
577 
578 
579 class BufferMemoryRequirementsDedicatedAllocation : public BufferMemoryRequirementsExtended
580 {
581 	static tcu::TestStatus testEntryPoint	(Context&									context,
582 											 const VkBufferCreateFlags					bufferFlags);
583 
584 protected:
585 	virtual void addFunctionTestCase		(tcu::TestCaseGroup*						group,
586 											 const std::string&							name,
587 											 VkBufferCreateFlags						arg0);
588 
589 	virtual void updateMemoryRequirements	(const DeviceInterface&						vk,
590 											 const VkDevice								device,
591 											 const VkDeviceSize							size,
592 											 const VkBufferCreateFlags					flags,
593 											 const VkBufferUsageFlags					usage,
594 											 const bool									all);
595 
596 	virtual void verifyMemoryRequirements	(tcu::ResultCollector&						result,
597 											 const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties,
598 											 const VkPhysicalDeviceLimits&				limits,
599 											 const VkBufferCreateFlags					bufferFlags,
600 											 const VkBufferUsageFlags					usage);
601 
602 protected:
603 	VkBool32	m_allUsageFlagsPrefersDedicatedAllocation;
604 	VkBool32	m_allUsageFlagsRequiresDedicatedAllocation;
605 
606 	VkBool32	m_currentTestPrefersDedicatedAllocation;
607 	VkBool32	m_currentTestRequiresDedicatedAllocation;
608 };
609 
610 
testEntryPoint(Context & context,const VkBufferCreateFlags bufferFlags)611 tcu::TestStatus BufferMemoryRequirementsDedicatedAllocation::testEntryPoint(Context& context, const VkBufferCreateFlags bufferFlags)
612 {
613 	BufferMemoryRequirementsDedicatedAllocation test;
614 
615 	return test.execTest(context, bufferFlags);
616 }
617 
checkSupportBufferMemoryRequirementsDedicatedAllocation(Context & context,VkBufferCreateFlags flags)618 void checkSupportBufferMemoryRequirementsDedicatedAllocation (Context& context, VkBufferCreateFlags flags)
619 {
620 	checkSupportBufferMemoryRequirementsExtended(context, flags);
621 
622 	context.requireDeviceFunctionality("VK_KHR_dedicated_allocation");
623 }
624 
addFunctionTestCase(tcu::TestCaseGroup * group,const std::string & name,VkBufferCreateFlags arg0)625 void BufferMemoryRequirementsDedicatedAllocation::addFunctionTestCase (tcu::TestCaseGroup*	group,
626 																	   const std::string&	name,
627 																	   VkBufferCreateFlags	arg0)
628 {
629 	addFunctionCase(group, name, checkSupportBufferMemoryRequirementsDedicatedAllocation, testEntryPoint, arg0);
630 }
631 
updateMemoryRequirements(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize size,const VkBufferCreateFlags flags,const VkBufferUsageFlags usage,const bool all)632 void BufferMemoryRequirementsDedicatedAllocation::updateMemoryRequirements (const DeviceInterface&		vk,
633 																			const VkDevice				device,
634 																			const VkDeviceSize			size,
635 																			const VkBufferCreateFlags	flags,
636 																			const VkBufferUsageFlags	usage,
637 																			const bool					all)
638 {
639 	const deUint32						invalidVkBool32			= static_cast<deUint32>(~0);
640 
641 	VkMemoryDedicatedRequirements	dedicatedRequirements	=
642 	{
643 		VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,		// VkStructureType	sType
644 		DE_NULL,												// void*			pNext
645 		invalidVkBool32,										// VkBool32			prefersDedicatedAllocation
646 		invalidVkBool32											// VkBool32			requiresDedicatedAllocation
647 	};
648 
649 	if (all)
650 	{
651 		m_allUsageFlagsRequirements					= getBufferMemoryRequirements2(vk, device, size, flags, usage, &dedicatedRequirements);
652 		m_allUsageFlagsPrefersDedicatedAllocation	= dedicatedRequirements.prefersDedicatedAllocation;
653 		m_allUsageFlagsRequiresDedicatedAllocation	= dedicatedRequirements.requiresDedicatedAllocation;
654 
655 		TCU_CHECK(validValueVkBool32(m_allUsageFlagsPrefersDedicatedAllocation));
656 		// Test design expects m_allUsageFlagsRequiresDedicatedAllocation to be false
657 		TCU_CHECK(m_allUsageFlagsRequiresDedicatedAllocation == VK_FALSE);
658 	}
659 	else
660 	{
661 		m_currentTestRequirements					= getBufferMemoryRequirements2(vk, device, size, flags, usage, &dedicatedRequirements);
662 		m_currentTestPrefersDedicatedAllocation		= dedicatedRequirements.prefersDedicatedAllocation;
663 		m_currentTestRequiresDedicatedAllocation	= dedicatedRequirements.requiresDedicatedAllocation;
664 	}
665 }
666 
verifyMemoryRequirements(tcu::ResultCollector & result,const VkPhysicalDeviceMemoryProperties & deviceMemoryProperties,const VkPhysicalDeviceLimits & limits,const VkBufferCreateFlags bufferFlags,const VkBufferUsageFlags usage)667 void BufferMemoryRequirementsDedicatedAllocation::verifyMemoryRequirements (tcu::ResultCollector&					result,
668 																			const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties,
669 																			const VkPhysicalDeviceLimits&			limits,
670 																			const VkBufferCreateFlags				bufferFlags,
671 																			const VkBufferUsageFlags				usage)
672 {
673 	BufferMemoryRequirementsExtended::verifyMemoryRequirements(result, deviceMemoryProperties, limits, bufferFlags, usage);
674 
675 	result.check(validValueVkBool32(m_currentTestPrefersDedicatedAllocation),
676 		"Invalid VkBool32 value in m_currentTestPrefersDedicatedAllocation");
677 
678 	result.check(m_currentTestRequiresDedicatedAllocation == VK_FALSE,
679 		"Regular (non-shared) objects must not require dedicated allocations");
680 }
681 
682 #ifndef CTS_USES_VULKANSC
683 class BufferMemoryRequirementsCreateInfo : public BufferMemoryRequirementsOriginal
684 {
685 	static tcu::TestStatus testEntryPoint	(Context&									context,
686 											 const VkBufferCreateFlags					bufferFlags);
687 
688 protected:
689 	virtual void addFunctionTestCase		(tcu::TestCaseGroup*						group,
690 											 const std::string&							name,
691 											 VkBufferCreateFlags						arg0);
692 
693 	virtual void updateMemoryRequirements	(const DeviceInterface&						vk,
694 											 const VkDevice								device,
695 											 const VkDeviceSize							size,
696 											 const VkBufferCreateFlags					flags,
697 											 const VkBufferUsageFlags					usage,
698 											 const bool									all);
699 
700 	virtual void verifyMemoryRequirements	(tcu::ResultCollector&						result,
701 											 const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties,
702 											 const VkPhysicalDeviceLimits&				limits,
703 											 const VkBufferCreateFlags					bufferFlags,
704 											 const VkBufferUsageFlags					usage);
705 
706 protected:
707 	VkMemoryRequirements	m_currentTestOriginalRequirements;
708 	VkMemoryRequirements	m_currentTestHalfRequirements;
709 };
710 
711 
testEntryPoint(Context & context,const VkBufferCreateFlags bufferFlags)712 tcu::TestStatus BufferMemoryRequirementsCreateInfo::testEntryPoint(Context& context, const VkBufferCreateFlags bufferFlags)
713 {
714 	BufferMemoryRequirementsCreateInfo test;
715 
716 	return test.execTest(context, bufferFlags);
717 }
718 
checkSupportBufferMemoryRequirementsCreateInfo(Context & context,VkBufferCreateFlags flags)719 void checkSupportBufferMemoryRequirementsCreateInfo (Context& context, VkBufferCreateFlags flags)
720 {
721 	checkSupportBufferMemoryRequirementsExtended(context, flags);
722 
723 	context.requireDeviceFunctionality("VK_KHR_maintenance4");
724 }
725 
addFunctionTestCase(tcu::TestCaseGroup * group,const std::string & name,VkBufferCreateFlags arg0)726 void BufferMemoryRequirementsCreateInfo::addFunctionTestCase(tcu::TestCaseGroup*	group,
727 															 const std::string&		name,
728 															 VkBufferCreateFlags	arg0)
729 {
730 	addFunctionCase(group, name, checkSupportBufferMemoryRequirementsCreateInfo, testEntryPoint, arg0);
731 }
732 
updateMemoryRequirements(const DeviceInterface & vk,const VkDevice device,const VkDeviceSize size,const VkBufferCreateFlags flags,const VkBufferUsageFlags usage,const bool all)733 void BufferMemoryRequirementsCreateInfo::updateMemoryRequirements	(const DeviceInterface&		vk,
734 																	 const VkDevice				device,
735 																	 const VkDeviceSize			size,
736 																	 const VkBufferCreateFlags	flags,
737 																	 const VkBufferUsageFlags	usage,
738 																	 const bool					all)
739 {
740 	if (all)
741 	{
742 		m_allUsageFlagsRequirements		= getBufferCreateInfoMemoryRequirementsKHR(vk, device, size, flags, usage);
743 	}
744 	else
745 	{
746 		m_currentTestRequirements		= getBufferCreateInfoMemoryRequirementsKHR(vk, device, size, flags, usage);
747 		m_currentTestHalfRequirements	= getBufferCreateInfoMemoryRequirementsKHR(vk, device, size / 2, flags, usage);
748 	}
749 
750 	m_currentTestOriginalRequirements = getBufferMemoryRequirements(vk, device, size, flags, usage);
751 }
752 
verifyMemoryRequirements(tcu::ResultCollector & result,const VkPhysicalDeviceMemoryProperties & deviceMemoryProperties,const VkPhysicalDeviceLimits & limits,const VkBufferCreateFlags bufferFlags,const VkBufferUsageFlags usage)753 void BufferMemoryRequirementsCreateInfo::verifyMemoryRequirements	(tcu::ResultCollector&						result,
754 																	 const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties,
755 																	 const VkPhysicalDeviceLimits&				limits,
756 																	 const VkBufferCreateFlags					bufferFlags,
757 																	 const VkBufferUsageFlags					usage)
758 {
759 	BufferMemoryRequirementsOriginal::verifyMemoryRequirements(result, deviceMemoryProperties, limits, bufferFlags, usage);
760 
761 	result.check(m_currentTestRequirements.alignment == m_currentTestOriginalRequirements.alignment,
762 			"VkMemoryRequirements alignment queried from vkBufferCreateInfo does not match alignment from equivalent object");
763 
764 	result.check(m_currentTestRequirements.memoryTypeBits == m_currentTestOriginalRequirements.memoryTypeBits,
765 			"VkMemoryRequirements memoryTypeBits queried from vkBufferCreateInfo does not match memoryTypeBits from equivalent object");
766 
767 	result.check(m_currentTestRequirements.size == m_currentTestOriginalRequirements.size,
768 			"VkMemoryRequirements size queried from vkBufferCreateInfo does not match size from equivalent object");
769 
770 	result.check(m_currentTestRequirements.size >= m_currentTestHalfRequirements.size,
771 			"VkMemoryRequirements size queried from vkBufferCreateInfo is larger for a smaller buffer");
772 }
773 #endif // CTS_USES_VULKANSC
774 
775 struct ImageTestParams
776 {
ImageTestParamsvkt::memory::__anon2f513b4b0111::ImageTestParams777 	ImageTestParams (VkImageCreateFlags		flags_,
778 					 VkImageTiling			tiling_,
779 					 bool					transient_,
780 					 bool					useMaint4_ = false)
781 	: flags		(flags_)
782 	, tiling	(tiling_)
783 	, transient	(transient_)
784 	, useMaint4	(useMaint4_)
785 	{
786 	}
787 
ImageTestParamsvkt::memory::__anon2f513b4b0111::ImageTestParams788 	ImageTestParams (void)
789 	{
790 	}
791 
792 	VkImageCreateFlags		flags;
793 	VkImageTiling			tiling;
794 	bool					transient;
795 	bool					useMaint4;
796 };
797 
798 class IImageMemoryRequirements
799 {
800 public:
801 	virtual void populateTestGroup			(tcu::TestCaseGroup*						group) = 0;
802 
803 protected:
804 	virtual void addFunctionTestCase		(tcu::TestCaseGroup*						group,
805 											 const std::string&							name,
806 											 const ImageTestParams						arg0) = 0;
807 
808 	virtual tcu::TestStatus execTest		(Context&									context,
809 											 const ImageTestParams						bufferFlags) = 0;
810 
811 	virtual void updateMemoryRequirements	(const DeviceInterface&						vk,
812 											 const VkDevice								device) = 0;
813 
814 	virtual void verifyMemoryRequirements	(tcu::ResultCollector&						result,
815 											 const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties) = 0;
816 };
817 
818 class ImageMemoryRequirementsOriginal : public IImageMemoryRequirements
819 {
820 	static tcu::TestStatus testEntryPoint	(Context&									context,
821 											 const ImageTestParams						params);
822 
823 public:
824 	virtual void populateTestGroup			(tcu::TestCaseGroup*						group);
825 
826 protected:
827 	virtual void addFunctionTestCase		(tcu::TestCaseGroup*						group,
828 											 const std::string&							name,
829 											 const ImageTestParams						arg0);
830 
831 	virtual tcu::TestStatus execTest		(Context&									context,
832 											 const ImageTestParams						params);
833 
834 	virtual void updateMemoryRequirements	(const DeviceInterface&						vk,
835 											 const VkDevice								device);
836 
837 	virtual void verifyMemoryRequirements	(tcu::ResultCollector&						result,
838 											 const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties);
839 
840 private:
841 	virtual bool isImageSupported			(const Context&								context,
842 											 const InstanceInterface&					vki,
843 											 const VkPhysicalDevice						physDevice,
844 											 const VkImageCreateInfo&					info);
845 
846 	virtual bool isFormatMatchingAspect		(const VkFormat								format,
847 											 const VkImageAspectFlags					aspect);
848 
849 protected:
850 	VkImageCreateInfo								m_currentTestImageInfo;
851 	VkMemoryRequirements							m_currentTestRequirements;
852 #ifndef CTS_USES_VULKANSC
853 	std::vector<VkSparseImageMemoryRequirements>	m_currentTestSparseRequirements;
854 #endif // CTS_USES_VULKANSC
855 };
856 
857 
testEntryPoint(Context & context,const ImageTestParams params)858 tcu::TestStatus ImageMemoryRequirementsOriginal::testEntryPoint (Context& context, const ImageTestParams params)
859 {
860 	ImageMemoryRequirementsOriginal test;
861 
862 	return test.execTest(context, params);
863 }
864 
populateTestGroup(tcu::TestCaseGroup * group)865 void ImageMemoryRequirementsOriginal::populateTestGroup (tcu::TestCaseGroup* group)
866 {
867 	const struct
868 	{
869 		VkImageCreateFlags		flags;
870 		bool					transient;
871 		const char* const		name;
872 	} imageFlagsCases[] =
873 	{
874 		{ (VkImageCreateFlags)0,																								false,	"regular"					},
875 		{ (VkImageCreateFlags)0,																								true,	"transient"					},
876 #ifndef CTS_USES_VULKANSC
877 		{ VK_IMAGE_CREATE_SPARSE_BINDING_BIT,																					false,	"sparse"					},
878 		{ VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,											false,	"sparse_residency"			},
879 		{ VK_IMAGE_CREATE_SPARSE_BINDING_BIT											| VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,	false,	"sparse_aliased"			},
880 		{ VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT		| VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,	false,	"sparse_residency_aliased"	},
881 #endif // CTS_USES_VULKANSC
882 	};
883 
884 	de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(group->getTestContext(), "image"));
885 
886 	for (int flagsNdx = 0; flagsNdx < DE_LENGTH_OF_ARRAY(imageFlagsCases); ++flagsNdx)
887 	for (int tilingNdx = 0; tilingNdx <= 1; ++tilingNdx)
888 	{
889 		ImageTestParams		params;
890 		std::ostringstream	caseName;
891 
892 		params.flags		=  imageFlagsCases[flagsNdx].flags;
893 		params.transient	=  imageFlagsCases[flagsNdx].transient;
894 		params.useMaint4	=  false;
895 		caseName			<< imageFlagsCases[flagsNdx].name;
896 
897 		if (tilingNdx != 0)
898 		{
899 			params.tiling =  VK_IMAGE_TILING_OPTIMAL;
900 			caseName      << "_tiling_optimal";
901 		}
902 		else
903 		{
904 			params.tiling =  VK_IMAGE_TILING_LINEAR;
905 			caseName      << "_tiling_linear";
906 		}
907 
908 		if ((params.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) && (params.tiling == VK_IMAGE_TILING_LINEAR))
909 			continue;
910 
911 		addFunctionTestCase(imageGroup.get(), caseName.str(), params);
912 	}
913 
914 	group->addChild(imageGroup.release());
915 }
916 
checkSupportImageMemoryRequirementsOriginal(Context & context,ImageTestParams params)917 void checkSupportImageMemoryRequirementsOriginal (Context& context, ImageTestParams params)
918 {
919 	const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(context.getInstanceInterface(), context.getPhysicalDevice());
920 
921 	if (params.flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT)
922 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_BINDING);
923 
924 	if (params.flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT)
925 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_ALIASED);
926 
927 	if ((params.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) && !(features.sparseResidencyImage2D || features.sparseResidencyImage3D))
928 		TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyImage (2D and 3D)");
929 }
930 
addFunctionTestCase(tcu::TestCaseGroup * group,const std::string & name,const ImageTestParams arg0)931 void ImageMemoryRequirementsOriginal::addFunctionTestCase (tcu::TestCaseGroup*		group,
932 														   const std::string&		name,
933 														   const ImageTestParams	arg0)
934 {
935 	addFunctionCase(group, name, checkSupportImageMemoryRequirementsOriginal, testEntryPoint, arg0);
936 }
937 
updateMemoryRequirements(const DeviceInterface & vk,const VkDevice device)938 void ImageMemoryRequirementsOriginal::updateMemoryRequirements	(const DeviceInterface&		vk,
939 																 const VkDevice				device)
940 {
941 	const Unique<VkImage> image(createImage(vk, device, &m_currentTestImageInfo));
942 
943 	m_currentTestRequirements = getImageMemoryRequirements(vk, device, *image);
944 
945 #ifndef CTS_USES_VULKANSC
946 	if (m_currentTestImageInfo.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)
947 		m_currentTestSparseRequirements = getImageSparseMemoryRequirements(vk, device, *image);
948 #endif // CTS_USES_VULKANSC
949 }
950 
verifyMemoryRequirements(tcu::ResultCollector & result,const VkPhysicalDeviceMemoryProperties & deviceMemoryProperties)951 void ImageMemoryRequirementsOriginal::verifyMemoryRequirements (tcu::ResultCollector&					result,
952 																const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties)
953 {
954 	if (result.check(m_currentTestRequirements.memoryTypeBits != 0, "VkMemoryRequirements memoryTypeBits has no bits set"))
955 	{
956 		typedef std::vector<deUint32>::const_iterator	IndexIterator;
957 		const std::vector<deUint32>						usedMemoryTypeIndices			= bitsToIndices(m_currentTestRequirements.memoryTypeBits);
958 		bool											deviceLocalMemoryFound			= false;
959 		bool											hostVisibleCoherentMemoryFound	= false;
960 
961 		for (IndexIterator memoryTypeNdx = usedMemoryTypeIndices.begin(); memoryTypeNdx != usedMemoryTypeIndices.end(); ++memoryTypeNdx)
962 		{
963 			if (*memoryTypeNdx >= deviceMemoryProperties.memoryTypeCount)
964 			{
965 				result.fail("VkMemoryRequirements memoryTypeBits contains bits for non-existing memory types");
966 				continue;
967 			}
968 
969 			const VkMemoryPropertyFlags	memoryPropertyFlags = deviceMemoryProperties.memoryTypes[*memoryTypeNdx].propertyFlags;
970 
971 			if (memoryPropertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
972 				deviceLocalMemoryFound = true;
973 
974 			if (memoryPropertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
975 				hostVisibleCoherentMemoryFound = true;
976 
977 			if (memoryPropertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
978 			{
979 				result.check((m_currentTestImageInfo.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0u,
980 					"Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT for a non-transient attachment image");
981 			}
982 		}
983 
984 		result.check(deIsPowerOfTwo64(static_cast<deUint64>(m_currentTestRequirements.alignment)) == DE_TRUE,
985 			"VkMemoryRequirements alignment isn't power of two");
986 
987 		result.check(deviceLocalMemoryFound,
988 			"None of the required memory types included VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT");
989 
990 		result.check(m_currentTestImageInfo.tiling == VK_IMAGE_TILING_OPTIMAL || hostVisibleCoherentMemoryFound,
991 			"Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and VK_MEMORY_PROPERTY_HOST_COHERENT_BIT");
992 
993 #ifndef CTS_USES_VULKANSC
994 		if (m_currentTestImageInfo.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)
995 		{
996 			for (const VkSparseImageMemoryRequirements &sparseRequirements : m_currentTestSparseRequirements)
997 			{
998 				result.check((sparseRequirements.imageMipTailSize % m_currentTestRequirements.alignment) == 0,
999 					"VkSparseImageMemoryRequirements imageMipTailSize is not aligned with sparse block size");
1000 			}
1001 		}
1002 #endif // CTS_USES_VULKANSC
1003 	}
1004 }
1005 
isUsageMatchesFeatures(const VkImageUsageFlags usage,const VkFormatFeatureFlags featureFlags)1006 bool isUsageMatchesFeatures (const VkImageUsageFlags usage, const VkFormatFeatureFlags featureFlags)
1007 {
1008 	if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) && (featureFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
1009 		return true;
1010 	if ((usage & VK_IMAGE_USAGE_STORAGE_BIT) && (featureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
1011 		return true;
1012 	if ((usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) && (featureFlags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
1013 		return true;
1014 	if ((usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && (featureFlags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
1015 		return true;
1016 
1017 	return false;
1018 }
1019 
doesUsageSatisfyFeatures(const VkImageUsageFlags usage,const VkFormatFeatureFlags featureFlags)1020 bool doesUsageSatisfyFeatures (const VkImageUsageFlags usage, const VkFormatFeatureFlags featureFlags)
1021 {
1022 	bool ans = true;
1023 
1024 	if (usage & VK_IMAGE_USAGE_SAMPLED_BIT)
1025 		ans &= ((featureFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0);
1026 	if (usage & VK_IMAGE_USAGE_STORAGE_BIT)
1027 		ans &= ((featureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0);
1028 	if (usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))
1029 		ans &= ((featureFlags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) != 0);
1030 	if (usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
1031 		ans &= ((featureFlags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0);
1032 
1033 	return ans;
1034 }
1035 
1036 //! This catches both invalid as well as legal but unsupported combinations of image parameters
isImageSupported(const Context & context,const InstanceInterface & vki,const VkPhysicalDevice physDevice,const VkImageCreateInfo & info)1037 bool ImageMemoryRequirementsOriginal::isImageSupported (const Context& context, const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkImageCreateInfo& info)
1038 {
1039 	DE_ASSERT(info.extent.width >= 1u && info.extent.height >= 1u && info.extent.depth >= 1u);
1040 
1041 #ifndef CTS_USES_VULKANSC
1042 	if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance5"))
1043 	{
1044 		if (info.format == VK_FORMAT_A8_UNORM_KHR || info.format == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR)
1045 			return false;
1046 	}
1047 #endif // CTS_USES_VULKANSC
1048 
1049 	if (isYCbCrFormat(info.format)
1050 		&& (info.imageType != VK_IMAGE_TYPE_2D
1051 			|| info.mipLevels != 1
1052 			|| info.arrayLayers != 1
1053 			|| info.samples != VK_SAMPLE_COUNT_1_BIT
1054 			|| !context.isDeviceFunctionalitySupported("VK_KHR_sampler_ycbcr_conversion")))
1055 	{
1056 		return false;
1057 	}
1058 
1059 	if (info.imageType == VK_IMAGE_TYPE_1D)
1060 	{
1061 		DE_ASSERT(info.extent.height == 1u && info.extent.depth == 1u);
1062 	}
1063 	else if (info.imageType == VK_IMAGE_TYPE_2D)
1064 	{
1065 		DE_ASSERT(info.extent.depth == 1u);
1066 
1067 		if (info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
1068 		{
1069 			DE_ASSERT(info.extent.width == info.extent.height);
1070 			DE_ASSERT(info.arrayLayers >= 6u && (info.arrayLayers % 6u) == 0u);
1071 		}
1072 	}
1073 
1074 	if ((info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && info.imageType != VK_IMAGE_TYPE_2D)
1075 		return false;
1076 
1077 	if ((info.samples != VK_SAMPLE_COUNT_1_BIT) &&
1078 		(info.imageType != VK_IMAGE_TYPE_2D || (info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) || info.tiling != VK_IMAGE_TILING_OPTIMAL || info.mipLevels > 1u))
1079 		return false;
1080 
1081 	if ((info.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) &&
1082 		(info.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) == 0u)
1083 		return false;
1084 
1085 	const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
1086 
1087 	if (info.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)
1088 	{
1089 		DE_ASSERT(info.tiling == VK_IMAGE_TILING_OPTIMAL);
1090 
1091 		if (info.imageType == VK_IMAGE_TYPE_1D)
1092 			return false;
1093 
1094 		if (info.imageType == VK_IMAGE_TYPE_2D && !features.sparseResidencyImage2D)
1095 			return false;
1096 		if (info.imageType == VK_IMAGE_TYPE_3D && !features.sparseResidencyImage3D)
1097 			return false;
1098 		if (info.samples == VK_SAMPLE_COUNT_2_BIT && !features.sparseResidency2Samples)
1099 			return false;
1100 		if (info.samples == VK_SAMPLE_COUNT_4_BIT && !features.sparseResidency4Samples)
1101 			return false;
1102 		if (info.samples == VK_SAMPLE_COUNT_8_BIT && !features.sparseResidency8Samples)
1103 			return false;
1104 		if (info.samples == VK_SAMPLE_COUNT_16_BIT && !features.sparseResidency16Samples)
1105 			return false;
1106 		if (info.samples == VK_SAMPLE_COUNT_32_BIT || info.samples == VK_SAMPLE_COUNT_64_BIT)
1107 			return false;
1108 	}
1109 
1110 	if (info.samples != VK_SAMPLE_COUNT_1_BIT && (info.usage & VK_IMAGE_USAGE_STORAGE_BIT) && !features.shaderStorageImageMultisample)
1111 		return false;
1112 
1113 	switch (info.format)
1114 	{
1115 		case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
1116 		case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
1117 		case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
1118 		case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
1119 		case VK_FORMAT_BC2_UNORM_BLOCK:
1120 		case VK_FORMAT_BC2_SRGB_BLOCK:
1121 		case VK_FORMAT_BC3_UNORM_BLOCK:
1122 		case VK_FORMAT_BC3_SRGB_BLOCK:
1123 		case VK_FORMAT_BC4_UNORM_BLOCK:
1124 		case VK_FORMAT_BC4_SNORM_BLOCK:
1125 		case VK_FORMAT_BC5_UNORM_BLOCK:
1126 		case VK_FORMAT_BC5_SNORM_BLOCK:
1127 		case VK_FORMAT_BC6H_UFLOAT_BLOCK:
1128 		case VK_FORMAT_BC6H_SFLOAT_BLOCK:
1129 		case VK_FORMAT_BC7_UNORM_BLOCK:
1130 		case VK_FORMAT_BC7_SRGB_BLOCK:
1131 			if (!features.textureCompressionBC)
1132 				return false;
1133 			break;
1134 
1135 		case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
1136 		case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
1137 		case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
1138 		case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
1139 		case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
1140 		case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
1141 		case VK_FORMAT_EAC_R11_UNORM_BLOCK:
1142 		case VK_FORMAT_EAC_R11_SNORM_BLOCK:
1143 		case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
1144 		case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
1145 			if (!features.textureCompressionETC2)
1146 				return false;
1147 			break;
1148 
1149 		case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
1150 		case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
1151 		case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
1152 		case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
1153 		case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
1154 		case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
1155 		case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
1156 		case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
1157 		case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
1158 		case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
1159 		case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
1160 		case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
1161 		case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
1162 		case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
1163 		case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
1164 		case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
1165 		case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
1166 		case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
1167 		case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
1168 		case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
1169 		case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
1170 		case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
1171 		case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
1172 		case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
1173 		case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
1174 		case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
1175 		case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
1176 		case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
1177 			if (!features.textureCompressionASTC_LDR)
1178 				return false;
1179 			break;
1180 
1181 		default:
1182 			break;
1183 	}
1184 
1185 	const VkFormatProperties	formatProperties	= getPhysicalDeviceFormatProperties(vki, physDevice, info.format);
1186 	const VkFormatFeatureFlags	formatFeatures		= (info.tiling == VK_IMAGE_TILING_LINEAR ? formatProperties.linearTilingFeatures
1187 																							 : formatProperties.optimalTilingFeatures);
1188 
1189 	if (!isUsageMatchesFeatures(info.usage, formatFeatures))
1190 		return false;
1191 
1192 	VkImageFormatProperties		imageFormatProperties;
1193 	const VkResult				result				= vki.getPhysicalDeviceImageFormatProperties(
1194 														physDevice, info.format, info.imageType, info.tiling, info.usage, info.flags, &imageFormatProperties);
1195 
1196 	if (result == VK_SUCCESS)
1197 	{
1198 		if (info.arrayLayers > imageFormatProperties.maxArrayLayers)
1199 			return false;
1200 		if (info.mipLevels > imageFormatProperties.maxMipLevels)
1201 			return false;
1202 		if ((info.samples & imageFormatProperties.sampleCounts) == 0u)
1203 			return false;
1204 	}
1205 
1206 #ifndef CTS_USES_VULKANSC
1207 	if ((info.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && !checkSparseImageFormatSupport(physDevice, vki, info))
1208 		return false;
1209 #endif // CTS_USES_VULKANSC
1210 
1211 	return result == VK_SUCCESS;
1212 }
1213 
makeExtentForImage(const VkImageType imageType)1214 VkExtent3D makeExtentForImage (const VkImageType imageType)
1215 {
1216 	VkExtent3D extent = { 64u, 64u, 4u };
1217 
1218 	if (imageType == VK_IMAGE_TYPE_1D)
1219 		extent.height = extent.depth = 1u;
1220 	else if (imageType == VK_IMAGE_TYPE_2D)
1221 		extent.depth = 1u;
1222 
1223 	return extent;
1224 }
1225 
1226 #ifndef CTS_USES_VULKANSC
halfExtentForImage(const VkImageType imageType,VkExtent3D extent)1227 VkExtent3D halfExtentForImage (const VkImageType imageType, VkExtent3D extent)
1228 {
1229 	VkExtent3D halfExtent = extent;
1230 
1231 	if (imageType == VK_IMAGE_TYPE_1D)
1232 		halfExtent.width /= 2;
1233 	else if (imageType == VK_IMAGE_TYPE_2D)
1234 		halfExtent.height /= 2;
1235 	else
1236 		halfExtent.depth /= 2;
1237 
1238 	return halfExtent;
1239 }
1240 #endif // CTS_USES_VULKANSC
1241 
isFormatMatchingAspect(const VkFormat format,const VkImageAspectFlags aspect)1242 bool ImageMemoryRequirementsOriginal::isFormatMatchingAspect (const VkFormat format, const VkImageAspectFlags aspect)
1243 {
1244 	DE_ASSERT(aspect == VK_IMAGE_ASPECT_COLOR_BIT || aspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
1245 
1246 	// D/S formats are laid out next to each other in the enum
1247 	const bool isDepthStencilFormat = (format >= VK_FORMAT_D16_UNORM && format <= VK_FORMAT_D32_SFLOAT_S8_UINT);
1248 
1249 	return (aspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == isDepthStencilFormat;
1250 }
1251 
getImageInfoString(const VkImageCreateInfo & imageInfo)1252 std::string getImageInfoString (const VkImageCreateInfo& imageInfo)
1253 {
1254 	std::ostringstream str;
1255 
1256 	switch (imageInfo.imageType)
1257 	{
1258 		case VK_IMAGE_TYPE_1D:			str << "1D "; break;
1259 		case VK_IMAGE_TYPE_2D:			str << "2D "; break;
1260 		case VK_IMAGE_TYPE_3D:			str << "3D "; break;
1261 		default:						break;
1262 	}
1263 
1264 	switch (imageInfo.tiling)
1265 	{
1266 		case VK_IMAGE_TILING_OPTIMAL:	str << "(optimal) "; break;
1267 		case VK_IMAGE_TILING_LINEAR:	str << "(linear) "; break;
1268 		default:						break;
1269 	}
1270 
1271 	str << "extent:[" << imageInfo.extent.width << ", " << imageInfo.extent.height << ", " << imageInfo.extent.depth << "] ";
1272 	str << imageInfo.format << " ";
1273 	str << "samples:" << static_cast<deUint32>(imageInfo.samples) << " ";
1274 	str << "flags:" << static_cast<deUint32>(imageInfo.flags) << " ";
1275 	str << "usage:" << static_cast<deUint32>(imageInfo.usage) << " ";
1276 
1277 	return str.str();
1278 }
1279 
execTest(Context & context,const ImageTestParams params)1280 tcu::TestStatus ImageMemoryRequirementsOriginal::execTest (Context& context, const ImageTestParams params)
1281 {
1282 	const VkFormat				formats[]		=
1283 	{
1284 		VK_FORMAT_R4G4_UNORM_PACK8,
1285 		VK_FORMAT_R4G4B4A4_UNORM_PACK16,
1286 		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
1287 		VK_FORMAT_R5G6B5_UNORM_PACK16,
1288 		VK_FORMAT_B5G6R5_UNORM_PACK16,
1289 		VK_FORMAT_R5G5B5A1_UNORM_PACK16,
1290 		VK_FORMAT_B5G5R5A1_UNORM_PACK16,
1291 		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
1292 #ifndef CTS_USES_VULKANSC
1293 		VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR,
1294 #endif // CTS_USES_VULKANSC
1295 		VK_FORMAT_R8_UNORM,
1296 		VK_FORMAT_R8_SNORM,
1297 		VK_FORMAT_R8_USCALED,
1298 		VK_FORMAT_R8_SSCALED,
1299 		VK_FORMAT_R8_UINT,
1300 		VK_FORMAT_R8_SINT,
1301 		VK_FORMAT_R8_SRGB,
1302 #ifndef CTS_USES_VULKANSC
1303 		VK_FORMAT_A8_UNORM_KHR,
1304 #endif // CTS_USES_VULKANSC
1305 		VK_FORMAT_R8G8_UNORM,
1306 		VK_FORMAT_R8G8_SNORM,
1307 		VK_FORMAT_R8G8_USCALED,
1308 		VK_FORMAT_R8G8_SSCALED,
1309 		VK_FORMAT_R8G8_UINT,
1310 		VK_FORMAT_R8G8_SINT,
1311 		VK_FORMAT_R8G8_SRGB,
1312 		VK_FORMAT_R8G8B8_UNORM,
1313 		VK_FORMAT_R8G8B8_SNORM,
1314 		VK_FORMAT_R8G8B8_USCALED,
1315 		VK_FORMAT_R8G8B8_SSCALED,
1316 		VK_FORMAT_R8G8B8_UINT,
1317 		VK_FORMAT_R8G8B8_SINT,
1318 		VK_FORMAT_R8G8B8_SRGB,
1319 		VK_FORMAT_B8G8R8_UNORM,
1320 		VK_FORMAT_B8G8R8_SNORM,
1321 		VK_FORMAT_B8G8R8_USCALED,
1322 		VK_FORMAT_B8G8R8_SSCALED,
1323 		VK_FORMAT_B8G8R8_UINT,
1324 		VK_FORMAT_B8G8R8_SINT,
1325 		VK_FORMAT_B8G8R8_SRGB,
1326 		VK_FORMAT_R8G8B8A8_UNORM,
1327 		VK_FORMAT_R8G8B8A8_SNORM,
1328 		VK_FORMAT_R8G8B8A8_USCALED,
1329 		VK_FORMAT_R8G8B8A8_SSCALED,
1330 		VK_FORMAT_R8G8B8A8_UINT,
1331 		VK_FORMAT_R8G8B8A8_SINT,
1332 		VK_FORMAT_R8G8B8A8_SRGB,
1333 		VK_FORMAT_B8G8R8A8_UNORM,
1334 		VK_FORMAT_B8G8R8A8_SNORM,
1335 		VK_FORMAT_B8G8R8A8_USCALED,
1336 		VK_FORMAT_B8G8R8A8_SSCALED,
1337 		VK_FORMAT_B8G8R8A8_UINT,
1338 		VK_FORMAT_B8G8R8A8_SINT,
1339 		VK_FORMAT_B8G8R8A8_SRGB,
1340 		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1341 		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1342 		VK_FORMAT_A8B8G8R8_USCALED_PACK32,
1343 		VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
1344 		VK_FORMAT_A8B8G8R8_UINT_PACK32,
1345 		VK_FORMAT_A8B8G8R8_SINT_PACK32,
1346 		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
1347 		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1348 		VK_FORMAT_A2R10G10B10_SNORM_PACK32,
1349 		VK_FORMAT_A2R10G10B10_USCALED_PACK32,
1350 		VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
1351 		VK_FORMAT_A2R10G10B10_UINT_PACK32,
1352 		VK_FORMAT_A2R10G10B10_SINT_PACK32,
1353 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1354 		VK_FORMAT_A2B10G10R10_SNORM_PACK32,
1355 		VK_FORMAT_A2B10G10R10_USCALED_PACK32,
1356 		VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
1357 		VK_FORMAT_A2B10G10R10_UINT_PACK32,
1358 		VK_FORMAT_A2B10G10R10_SINT_PACK32,
1359 		VK_FORMAT_R16_UNORM,
1360 		VK_FORMAT_R16_SNORM,
1361 		VK_FORMAT_R16_USCALED,
1362 		VK_FORMAT_R16_SSCALED,
1363 		VK_FORMAT_R16_UINT,
1364 		VK_FORMAT_R16_SINT,
1365 		VK_FORMAT_R16_SFLOAT,
1366 		VK_FORMAT_R16G16_UNORM,
1367 		VK_FORMAT_R16G16_SNORM,
1368 		VK_FORMAT_R16G16_USCALED,
1369 		VK_FORMAT_R16G16_SSCALED,
1370 		VK_FORMAT_R16G16_UINT,
1371 		VK_FORMAT_R16G16_SINT,
1372 		VK_FORMAT_R16G16_SFLOAT,
1373 		VK_FORMAT_R16G16B16_UNORM,
1374 		VK_FORMAT_R16G16B16_SNORM,
1375 		VK_FORMAT_R16G16B16_USCALED,
1376 		VK_FORMAT_R16G16B16_SSCALED,
1377 		VK_FORMAT_R16G16B16_UINT,
1378 		VK_FORMAT_R16G16B16_SINT,
1379 		VK_FORMAT_R16G16B16_SFLOAT,
1380 		VK_FORMAT_R16G16B16A16_UNORM,
1381 		VK_FORMAT_R16G16B16A16_SNORM,
1382 		VK_FORMAT_R16G16B16A16_USCALED,
1383 		VK_FORMAT_R16G16B16A16_SSCALED,
1384 		VK_FORMAT_R16G16B16A16_UINT,
1385 		VK_FORMAT_R16G16B16A16_SINT,
1386 		VK_FORMAT_R16G16B16A16_SFLOAT,
1387 		VK_FORMAT_R32_UINT,
1388 		VK_FORMAT_R32_SINT,
1389 		VK_FORMAT_R32_SFLOAT,
1390 		VK_FORMAT_R32G32_UINT,
1391 		VK_FORMAT_R32G32_SINT,
1392 		VK_FORMAT_R32G32_SFLOAT,
1393 		VK_FORMAT_R32G32B32_UINT,
1394 		VK_FORMAT_R32G32B32_SINT,
1395 		VK_FORMAT_R32G32B32_SFLOAT,
1396 		VK_FORMAT_R32G32B32A32_UINT,
1397 		VK_FORMAT_R32G32B32A32_SINT,
1398 		VK_FORMAT_R32G32B32A32_SFLOAT,
1399 		VK_FORMAT_R64_UINT,
1400 		VK_FORMAT_R64_SINT,
1401 		VK_FORMAT_R64_SFLOAT,
1402 		VK_FORMAT_R64G64_UINT,
1403 		VK_FORMAT_R64G64_SINT,
1404 		VK_FORMAT_R64G64_SFLOAT,
1405 		VK_FORMAT_R64G64B64_UINT,
1406 		VK_FORMAT_R64G64B64_SINT,
1407 		VK_FORMAT_R64G64B64_SFLOAT,
1408 		VK_FORMAT_R64G64B64A64_UINT,
1409 		VK_FORMAT_R64G64B64A64_SINT,
1410 		VK_FORMAT_R64G64B64A64_SFLOAT,
1411 		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
1412 		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
1413 		VK_FORMAT_D16_UNORM,
1414 		VK_FORMAT_X8_D24_UNORM_PACK32,
1415 		VK_FORMAT_D32_SFLOAT,
1416 		VK_FORMAT_S8_UINT,
1417 		VK_FORMAT_D16_UNORM_S8_UINT,
1418 		VK_FORMAT_D24_UNORM_S8_UINT,
1419 		VK_FORMAT_D32_SFLOAT_S8_UINT,
1420 		VK_FORMAT_BC1_RGB_UNORM_BLOCK,
1421 		VK_FORMAT_BC1_RGB_SRGB_BLOCK,
1422 		VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
1423 		VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
1424 		VK_FORMAT_BC2_UNORM_BLOCK,
1425 		VK_FORMAT_BC2_SRGB_BLOCK,
1426 		VK_FORMAT_BC3_UNORM_BLOCK,
1427 		VK_FORMAT_BC3_SRGB_BLOCK,
1428 		VK_FORMAT_BC4_UNORM_BLOCK,
1429 		VK_FORMAT_BC4_SNORM_BLOCK,
1430 		VK_FORMAT_BC5_UNORM_BLOCK,
1431 		VK_FORMAT_BC5_SNORM_BLOCK,
1432 		VK_FORMAT_BC6H_UFLOAT_BLOCK,
1433 		VK_FORMAT_BC6H_SFLOAT_BLOCK,
1434 		VK_FORMAT_BC7_UNORM_BLOCK,
1435 		VK_FORMAT_BC7_SRGB_BLOCK,
1436 		VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
1437 		VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
1438 		VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
1439 		VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
1440 		VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
1441 		VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
1442 		VK_FORMAT_EAC_R11_UNORM_BLOCK,
1443 		VK_FORMAT_EAC_R11_SNORM_BLOCK,
1444 		VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
1445 		VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
1446 		VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
1447 		VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
1448 		VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
1449 		VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
1450 		VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
1451 		VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
1452 		VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
1453 		VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
1454 		VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
1455 		VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
1456 		VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
1457 		VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
1458 		VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
1459 		VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
1460 		VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
1461 		VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
1462 		VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
1463 		VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
1464 		VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
1465 		VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
1466 		VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
1467 		VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
1468 		VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
1469 		VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
1470 		VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
1471 		VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
1472 		VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
1473 		VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
1474 		VK_FORMAT_G8B8G8R8_422_UNORM,
1475 		VK_FORMAT_B8G8R8G8_422_UNORM,
1476 		VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
1477 		VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
1478 		VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
1479 		VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
1480 		VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM,
1481 		VK_FORMAT_R10X6_UNORM_PACK16,
1482 		VK_FORMAT_R10X6G10X6_UNORM_2PACK16,
1483 		VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
1484 		VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
1485 		VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16,
1486 		VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,
1487 		VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
1488 		VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,
1489 		VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
1490 		VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,
1491 		VK_FORMAT_R12X4_UNORM_PACK16,
1492 		VK_FORMAT_R12X4G12X4_UNORM_2PACK16,
1493 		VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
1494 		VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
1495 		VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16,
1496 		VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,
1497 		VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
1498 		VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,
1499 		VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
1500 		VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,
1501 		VK_FORMAT_G16B16G16R16_422_UNORM,
1502 		VK_FORMAT_B16G16R16G16_422_UNORM,
1503 		VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM,
1504 		VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,
1505 		VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM,
1506 		VK_FORMAT_G16_B16R16_2PLANE_422_UNORM,
1507 		VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM,
1508 		VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
1509 		VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
1510 		VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT,
1511 		VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT,
1512 		VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT,
1513 		VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT,
1514 	};
1515 	const DeviceInterface&		vk				= context.getDeviceInterface();
1516 	const InstanceInterface&	vki				= context.getInstanceInterface();
1517 	const VkDevice				device			= context.getDevice();
1518 	const VkPhysicalDevice		physDevice		= context.getPhysicalDevice();
1519 	const VkImageCreateFlags	sparseFlags		= VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT;
1520 	const VkImageUsageFlags		transientFlags	= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
1521 
1522 	const VkPhysicalDeviceMemoryProperties	memoryProperties		= getPhysicalDeviceMemoryProperties(vki, physDevice);
1523 	const deUint32							notInitializedBits		= ~0u;
1524 	const VkImageAspectFlags				colorAspect				= VK_IMAGE_ASPECT_COLOR_BIT;
1525 	const VkImageAspectFlags				depthStencilAspect		= VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1526 	const VkImageAspectFlags				allAspects[2]			= { colorAspect, depthStencilAspect };
1527 	tcu::TestLog&							log						= context.getTestContext().getLog();
1528 	bool									allPass					= true;
1529 	deUint32								numCheckedImages		= 0u;
1530 
1531 	log << tcu::TestLog::Message << "Verify memory requirements for the following parameter combinations:" << tcu::TestLog::EndMessage;
1532 
1533 	for (deUint32 loopAspectNdx = 0u; loopAspectNdx < DE_LENGTH_OF_ARRAY(allAspects); ++loopAspectNdx)
1534 	{
1535 		const VkImageAspectFlags	aspect					= allAspects[loopAspectNdx];
1536 		deUint32					previousMemoryTypeBits	= notInitializedBits;
1537 
1538 		for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1539 		{
1540 			const VkFormat format = formats[formatNdx];
1541 
1542 			if  (isFormatMatchingAspect(format, aspect))
1543 			{
1544 				// memoryTypeBits may differ between depth/stencil formats
1545 				if (aspect == depthStencilAspect)
1546 					previousMemoryTypeBits = notInitializedBits;
1547 
1548 				for (VkImageType			loopImageType	= VK_IMAGE_TYPE_1D;					loopImageType	!= VK_IMAGE_TYPE_LAST;					loopImageType	= nextEnum(loopImageType))
1549 				for (VkImageCreateFlags		loopCreateFlags	= (VkImageCreateFlags)0;			loopCreateFlags	<= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;	loopCreateFlags	= nextFlagExcluding(loopCreateFlags, sparseFlags))
1550 				for (VkImageUsageFlags		loopUsageFlags	= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;	loopUsageFlags	<= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;	loopUsageFlags	= nextFlagExcluding(loopUsageFlags, transientFlags))
1551 				for (VkSampleCountFlagBits	loopSampleCount	= VK_SAMPLE_COUNT_1_BIT;			loopSampleCount	<= VK_SAMPLE_COUNT_16_BIT;				loopSampleCount	= nextFlag(loopSampleCount))
1552 				{
1553 					const VkImageCreateFlags	actualCreateFlags	= loopCreateFlags | params.flags;
1554 					const VkImageUsageFlags		actualUsageFlags	= loopUsageFlags  | (params.transient ? VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0);
1555 					const bool					isCube				= (actualCreateFlags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) != 0u;
1556 					const VkImageCreateInfo		imageInfo			=
1557 					{
1558 						VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType          sType;
1559 						DE_NULL,									// const void*              pNext;
1560 						actualCreateFlags,							// VkImageCreateFlags       flags;
1561 						loopImageType,								// VkImageType              imageType;
1562 						format,									// VkFormat                 format;
1563 						makeExtentForImage(loopImageType),			// VkExtent3D               extent;
1564 						1u,											// uint32_t                 mipLevels;
1565 						(isCube ? 6u : 1u),							// uint32_t                 arrayLayers;
1566 						loopSampleCount,							// VkSampleCountFlagBits    samples;
1567 						params.tiling,								// VkImageTiling            tiling;
1568 						actualUsageFlags,							// VkImageUsageFlags        usage;
1569 						VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode            sharingMode;
1570 						0u,											// uint32_t                 queueFamilyIndexCount;
1571 						DE_NULL,									// const uint32_t*          pQueueFamilyIndices;
1572 						VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout            initialLayout;
1573 					};
1574 
1575 					m_currentTestImageInfo = imageInfo;
1576 
1577 					if (!isImageSupported(context, vki, physDevice, m_currentTestImageInfo))
1578 						continue;
1579 
1580 					log << tcu::TestLog::Message << "- " << getImageInfoString(m_currentTestImageInfo) << tcu::TestLog::EndMessage;
1581 					++numCheckedImages;
1582 
1583 					tcu::ResultCollector result(log, "ERROR: ");
1584 
1585 					updateMemoryRequirements(vk, device);
1586 
1587 					verifyMemoryRequirements(result, memoryProperties);
1588 
1589 					// For the same tiling, transient usage, and sparse flags, (and format, if D/S) memoryTypeBits must be the same for all images
1590 					result.check((previousMemoryTypeBits == notInitializedBits) || (m_currentTestRequirements.memoryTypeBits == previousMemoryTypeBits),
1591 									"memoryTypeBits differ from the ones in the previous image configuration");
1592 
1593 					if (result.getResult() != QP_TEST_RESULT_PASS)
1594 						allPass = false;
1595 
1596 					previousMemoryTypeBits = m_currentTestRequirements.memoryTypeBits;
1597 				}
1598 			}
1599 		}
1600 	}
1601 
1602 	if (numCheckedImages == 0u)
1603 		log << tcu::TestLog::Message << "NOTE: No supported image configurations -- nothing to check" << tcu::TestLog::EndMessage;
1604 
1605 	return allPass ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Some memory requirements were incorrect");
1606 }
1607 
1608 
1609 class ImageMemoryRequirementsExtended : public ImageMemoryRequirementsOriginal
1610 {
1611 public:
1612 	static tcu::TestStatus testEntryPoint	(Context&									context,
1613 											 const ImageTestParams						params);
1614 
1615 protected:
1616 	virtual void addFunctionTestCase		(tcu::TestCaseGroup*						group,
1617 											 const std::string&							name,
1618 											 const ImageTestParams						arg0);
1619 
1620 	virtual void updateMemoryRequirements	(const DeviceInterface&						vk,
1621 											 const VkDevice								device);
1622 };
1623 
1624 
testEntryPoint(Context & context,const ImageTestParams params)1625 tcu::TestStatus ImageMemoryRequirementsExtended::testEntryPoint (Context& context, const ImageTestParams params)
1626 {
1627 	ImageMemoryRequirementsExtended test;
1628 
1629 	return test.execTest(context, params);
1630 }
1631 
checkSupportImageMemoryRequirementsExtended(Context & context,ImageTestParams params)1632 void checkSupportImageMemoryRequirementsExtended (Context& context, ImageTestParams params)
1633 {
1634 	checkSupportImageMemoryRequirementsOriginal(context, params);
1635 
1636 	context.requireDeviceFunctionality("VK_KHR_get_memory_requirements2");
1637 }
1638 
addFunctionTestCase(tcu::TestCaseGroup * group,const std::string & name,const ImageTestParams arg0)1639 void ImageMemoryRequirementsExtended::addFunctionTestCase (tcu::TestCaseGroup*		group,
1640 														   const std::string&		name,
1641 														   const ImageTestParams	arg0)
1642 {
1643 	addFunctionCase(group, name, checkSupportImageMemoryRequirementsExtended, testEntryPoint, arg0);
1644 }
1645 
updateMemoryRequirements(const DeviceInterface & vk,const VkDevice device)1646 void ImageMemoryRequirementsExtended::updateMemoryRequirements (const DeviceInterface&		vk,
1647 															    const VkDevice				device)
1648 {
1649 	m_currentTestRequirements = getImageMemoryRequirements2(vk, device, m_currentTestImageInfo);
1650 }
1651 
1652 
1653 class ImageMemoryRequirementsDedicatedAllocation : public ImageMemoryRequirementsExtended
1654 {
1655 public:
1656 	static tcu::TestStatus testEntryPoint	(Context&									context,
1657 											 const ImageTestParams						params);
1658 
1659 protected:
1660 	virtual void addFunctionTestCase		(tcu::TestCaseGroup*						group,
1661 											 const std::string&							name,
1662 											 const ImageTestParams						arg0);
1663 
1664 	virtual void updateMemoryRequirements	(const DeviceInterface&						vk,
1665 											 const VkDevice								device);
1666 
1667 	virtual void verifyMemoryRequirements	(tcu::ResultCollector&						result,
1668 											 const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties);
1669 
1670 protected:
1671 	VkBool32	m_currentTestPrefersDedicatedAllocation;
1672 	VkBool32	m_currentTestRequiresDedicatedAllocation;
1673 };
1674 
1675 
testEntryPoint(Context & context,const ImageTestParams params)1676 tcu::TestStatus ImageMemoryRequirementsDedicatedAllocation::testEntryPoint (Context& context, const ImageTestParams params)
1677 {
1678 	ImageMemoryRequirementsDedicatedAllocation test;
1679 
1680 	return test.execTest(context, params);
1681 }
1682 
checkSupportImageMemoryRequirementsDedicatedAllocation(Context & context,ImageTestParams params)1683 void checkSupportImageMemoryRequirementsDedicatedAllocation (Context& context, ImageTestParams params)
1684 {
1685 	checkSupportImageMemoryRequirementsExtended(context, params);
1686 
1687 	context.requireDeviceFunctionality("VK_KHR_dedicated_allocation");
1688 }
1689 
addFunctionTestCase(tcu::TestCaseGroup * group,const std::string & name,const ImageTestParams arg0)1690 void ImageMemoryRequirementsDedicatedAllocation::addFunctionTestCase (tcu::TestCaseGroup*		group,
1691 																	  const std::string&		name,
1692 																	  const ImageTestParams		arg0)
1693 {
1694 	addFunctionCase(group, name, checkSupportImageMemoryRequirementsDedicatedAllocation, testEntryPoint, arg0);
1695 }
1696 
updateMemoryRequirements(const DeviceInterface & vk,const VkDevice device)1697 void ImageMemoryRequirementsDedicatedAllocation::updateMemoryRequirements (const DeviceInterface&	vk,
1698 																		   const VkDevice			device)
1699 {
1700 	const deUint32						invalidVkBool32			= static_cast<deUint32>(~0);
1701 
1702 	VkMemoryDedicatedRequirements	dedicatedRequirements	=
1703 	{
1704 		VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,		// VkStructureType	sType
1705 		DE_NULL,												// void*			pNext
1706 		invalidVkBool32,										// VkBool32			prefersDedicatedAllocation
1707 		invalidVkBool32											// VkBool32			requiresDedicatedAllocation
1708 	};
1709 
1710 	m_currentTestRequirements					= getImageMemoryRequirements2(vk, device, m_currentTestImageInfo, &dedicatedRequirements);
1711 	m_currentTestPrefersDedicatedAllocation		= dedicatedRequirements.prefersDedicatedAllocation;
1712 	m_currentTestRequiresDedicatedAllocation	= dedicatedRequirements.requiresDedicatedAllocation;
1713 }
1714 
verifyMemoryRequirements(tcu::ResultCollector & result,const VkPhysicalDeviceMemoryProperties & deviceMemoryProperties)1715 void ImageMemoryRequirementsDedicatedAllocation::verifyMemoryRequirements (tcu::ResultCollector&						result,
1716 																		   const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties)
1717 {
1718 	ImageMemoryRequirementsExtended::verifyMemoryRequirements(result, deviceMemoryProperties);
1719 
1720 	result.check(validValueVkBool32(m_currentTestPrefersDedicatedAllocation),
1721 		"Non-bool value in m_currentTestPrefersDedicatedAllocation");
1722 
1723 	result.check(m_currentTestRequiresDedicatedAllocation == VK_FALSE,
1724 		"Test design expects m_currentTestRequiresDedicatedAllocation to be false");
1725 }
1726 
1727 #ifndef CTS_USES_VULKANSC
1728 class ImageMemoryRequirementsCreateInfo : public ImageMemoryRequirementsExtended
1729 {
1730 public:
1731 	static tcu::TestStatus testEntryPoint	(Context&									context,
1732 											 const ImageTestParams						params);
1733 
1734 protected:
1735 	virtual void addFunctionTestCase		(tcu::TestCaseGroup*						group,
1736 											 const std::string&							name,
1737 											 const ImageTestParams						arg0);
1738 
1739 	virtual void updateMemoryRequirements	(const DeviceInterface&						vk,
1740 											 const VkDevice								device);
1741 
1742 	virtual void verifyMemoryRequirements	(tcu::ResultCollector&						result,
1743 											 const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties);
1744 
1745 	VkMemoryRequirements							m_currentTestOriginalRequirements;
1746 	VkMemoryRequirements							m_currentTestHalfRequirements;
1747 	std::vector<VkSparseImageMemoryRequirements>	m_currentTestOriginalSparseRequirements;
1748 };
1749 
1750 
testEntryPoint(Context & context,const ImageTestParams params)1751 tcu::TestStatus ImageMemoryRequirementsCreateInfo::testEntryPoint (Context& context, const ImageTestParams params)
1752 {
1753 	ImageMemoryRequirementsCreateInfo test;
1754 
1755 	return test.execTest(context, params);
1756 }
1757 
checkSupportImageMemoryRequirementsCreateInfo(Context & context,ImageTestParams params)1758 void checkSupportImageMemoryRequirementsCreateInfo (Context& context, ImageTestParams params)
1759 {
1760 	checkSupportImageMemoryRequirementsExtended(context, params);
1761 
1762 	context.requireDeviceFunctionality("VK_KHR_maintenance4");
1763 }
1764 
addFunctionTestCase(tcu::TestCaseGroup * group,const std::string & name,const ImageTestParams arg0)1765 void ImageMemoryRequirementsCreateInfo::addFunctionTestCase (tcu::TestCaseGroup*	group,
1766 															 const std::string&		name,
1767 															 const ImageTestParams	arg0)
1768 {
1769 	addFunctionCase(group, name, checkSupportImageMemoryRequirementsCreateInfo, testEntryPoint, arg0);
1770 }
1771 
updateMemoryRequirements(const DeviceInterface & vk,const VkDevice device)1772 void ImageMemoryRequirementsCreateInfo::updateMemoryRequirements (const DeviceInterface&	vk,
1773 																  const VkDevice			device)
1774 {
1775 	m_currentTestRequirements = getDeviceImageMemoryRequirements(vk, device, m_currentTestImageInfo);
1776 
1777 	const Unique<VkImage> image(createImage(vk, device, &m_currentTestImageInfo));
1778 	m_currentTestOriginalRequirements = getImageMemoryRequirements(vk, device, *image);
1779 
1780 	VkImageCreateInfo halfImageCreateInfo = m_currentTestImageInfo;
1781 	halfImageCreateInfo.extent = halfExtentForImage(m_currentTestImageInfo.imageType, m_currentTestImageInfo.extent);
1782 	m_currentTestHalfRequirements = getDeviceImageMemoryRequirements(vk, device, halfImageCreateInfo);
1783 
1784 	if (m_currentTestImageInfo.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)
1785 	{
1786 		m_currentTestSparseRequirements = getImageCreateInfoSparseMemoryRequirements(vk, device, m_currentTestImageInfo);
1787 		m_currentTestOriginalSparseRequirements = getImageSparseMemoryRequirements(vk, device, *image);
1788 	}
1789 }
1790 
verifyMemoryRequirements(tcu::ResultCollector & result,const VkPhysicalDeviceMemoryProperties & deviceMemoryProperties)1791 void ImageMemoryRequirementsCreateInfo::verifyMemoryRequirements (tcu::ResultCollector&					result,
1792 																  const VkPhysicalDeviceMemoryProperties&	deviceMemoryProperties)
1793 {
1794 	ImageMemoryRequirementsOriginal::verifyMemoryRequirements(result, deviceMemoryProperties);
1795 
1796 	result.check(m_currentTestRequirements.alignment == m_currentTestOriginalRequirements.alignment,
1797 			"VkMemoryRequirements alignment queried from vkImageCreateInfo differs from equivalent object query");
1798 
1799 	result.check(m_currentTestRequirements.memoryTypeBits == m_currentTestOriginalRequirements.memoryTypeBits,
1800 			"VkMemoryRequirements memoryTypeBits queried from vkImageCreateInfo differs from equivalent object query");
1801 
1802 	result.check(m_currentTestRequirements.size == m_currentTestOriginalRequirements.size,
1803 			"VkMemoryRequirements size queried from vkImageCreateInfo differs from equivalent object query");
1804 
1805 	result.check(m_currentTestRequirements.size >= m_currentTestHalfRequirements.size,
1806 			"VkMemoryRequirements size queried from vkImageCreateInfo is larger for a smaller image");
1807 
1808 	if (m_currentTestImageInfo.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)
1809 	{
1810 		result.check(m_currentTestSparseRequirements.size() == m_currentTestOriginalSparseRequirements.size(),
1811 			"VkSparseImageMemoryRequirements count queried from vkImageCreateInfo differs from equivalent object query");
1812 
1813 		for (deUint32 ndx = 0; ndx < m_currentTestSparseRequirements.size(); ++ndx)
1814 		{
1815 			const VkSparseImageMemoryRequirements &sparseRequirementsFromCreateInfo	= m_currentTestSparseRequirements[ndx];
1816 			const VkSparseImageMemoryRequirements &sparseRequirementsFromObject		= m_currentTestOriginalSparseRequirements[ndx];
1817 
1818 			result.check(sparseRequirementsFromCreateInfo.formatProperties.aspectMask == sparseRequirementsFromObject.formatProperties.aspectMask,
1819 				"VkSparseImageMemoryRequirements aspectMask queried from vkImageCreateInfo differs from equivalent object query");
1820 
1821 			result.check(sparseRequirementsFromCreateInfo.formatProperties.flags == sparseRequirementsFromObject.formatProperties.flags,
1822 				"VkSparseImageMemoryRequirements flags queried from vkImageCreateInfo differs from equivalent object query");
1823 
1824 			result.check(sparseRequirementsFromCreateInfo.formatProperties.imageGranularity.width == sparseRequirementsFromObject.formatProperties.imageGranularity.width,
1825 				"VkSparseImageMemoryRequirements imageGranularity queried from vkImageCreateInfo differs from equivalent object query");
1826 			result.check(sparseRequirementsFromCreateInfo.formatProperties.imageGranularity.height == sparseRequirementsFromObject.formatProperties.imageGranularity.height,
1827 				"VkSparseImageMemoryRequirements imageGranularity queried from vkImageCreateInfo differs from equivalent object query");
1828 			result.check(sparseRequirementsFromCreateInfo.formatProperties.imageGranularity.depth == sparseRequirementsFromObject.formatProperties.imageGranularity.depth,
1829 				"VkSparseImageMemoryRequirements imageGranularity queried from vkImageCreateInfo differs from equivalent object query");
1830 
1831 			result.check(sparseRequirementsFromCreateInfo.imageMipTailFirstLod == sparseRequirementsFromObject.imageMipTailFirstLod,
1832 				"VkSparseImageMemoryRequirements imageMipTailFirstLod queried from vkImageCreateInfo differs from equivalent object query");
1833 
1834 			result.check(sparseRequirementsFromCreateInfo.imageMipTailSize == sparseRequirementsFromObject.imageMipTailSize,
1835 				"VkSparseImageMemoryRequirements imageMipTailSize queried from vkImageCreateInfo differs from equivalent object query");
1836 
1837 			result.check(sparseRequirementsFromCreateInfo.imageMipTailOffset == sparseRequirementsFromObject.imageMipTailOffset,
1838 				"VkSparseImageMemoryRequirements imageMipTailOffset queried from vkImageCreateInfo differs from equivalent object query");
1839 
1840 			result.check(sparseRequirementsFromCreateInfo.imageMipTailStride == sparseRequirementsFromObject.imageMipTailStride,
1841 				"VkSparseImageMemoryRequirements imageMipTailStride queried from vkImageCreateInfo differs from equivalent object query");
1842 		}
1843 	}
1844 }
1845 #endif // CTS_USES_VULKANSC
1846 
populateCoreTestGroup(tcu::TestCaseGroup * group)1847 void populateCoreTestGroup (tcu::TestCaseGroup* group)
1848 {
1849 	BufferMemoryRequirementsOriginal	bufferTest;
1850 	ImageMemoryRequirementsOriginal		imageTest;
1851 
1852 	bufferTest.populateTestGroup(group);
1853 	imageTest.populateTestGroup(group);
1854 }
1855 
populateExtendedTestGroup(tcu::TestCaseGroup * group)1856 void populateExtendedTestGroup (tcu::TestCaseGroup* group)
1857 {
1858 	BufferMemoryRequirementsExtended	bufferTest;
1859 	ImageMemoryRequirementsExtended		imageTest;
1860 
1861 	bufferTest.populateTestGroup(group);
1862 	imageTest.populateTestGroup(group);
1863 }
1864 
populateDedicatedAllocationTestGroup(tcu::TestCaseGroup * group)1865 void populateDedicatedAllocationTestGroup (tcu::TestCaseGroup* group)
1866 {
1867 	BufferMemoryRequirementsDedicatedAllocation	bufferTest;
1868 	ImageMemoryRequirementsDedicatedAllocation	imageTest;
1869 
1870 	bufferTest.populateTestGroup(group);
1871 	imageTest.populateTestGroup(group);
1872 }
1873 
isMultiplaneImageSupported(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice,const VkImageCreateInfo & info)1874 bool isMultiplaneImageSupported (const InstanceInterface&	vki,
1875 								 const VkPhysicalDevice		physicalDevice,
1876 								 const VkImageCreateInfo&	info)
1877 {
1878 	// cubemap requires arrayLayers > 1, which multiplane doesn't support
1879 	if (info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
1880 		return false;
1881 
1882 	if ((info.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) &&
1883 		(info.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) == 0u)
1884 		return false;
1885 
1886 	const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physicalDevice);
1887 
1888 	if (info.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)
1889 	{
1890 		DE_ASSERT(info.tiling == VK_IMAGE_TILING_OPTIMAL);
1891 
1892 		if (info.imageType == VK_IMAGE_TYPE_2D && !features.sparseResidencyImage2D)
1893 			return false;
1894 	}
1895 
1896 	const VkFormatProperties	formatProperties	= getPhysicalDeviceFormatProperties(vki, physicalDevice, info.format);
1897 	const VkFormatFeatureFlags	formatFeatures		= (info.tiling == VK_IMAGE_TILING_LINEAR ? formatProperties.linearTilingFeatures
1898 																							 : formatProperties.optimalTilingFeatures);
1899 	if ((info.flags & VK_IMAGE_CREATE_DISJOINT_BIT) != 0 && (formatFeatures & VK_FORMAT_FEATURE_DISJOINT_BIT) == 0)
1900 		return false;
1901 
1902 	if (!doesUsageSatisfyFeatures(info.usage, formatFeatures))
1903 		return false;
1904 
1905 	VkImageFormatProperties		imageFormatProperties;
1906 	const VkResult				result				= vki.getPhysicalDeviceImageFormatProperties(
1907 														physicalDevice, info.format, info.imageType, info.tiling, info.usage, info.flags, &imageFormatProperties);
1908 
1909 	if (VK_SUCCESS == result)
1910 	{
1911 		if (info.arrayLayers > imageFormatProperties.maxArrayLayers)
1912 			return false;
1913 		if (info.mipLevels > imageFormatProperties.maxMipLevels)
1914 			return false;
1915 		if ((info.samples & imageFormatProperties.sampleCounts) == 0u)
1916 			return false;
1917 	}
1918 
1919 	return (VK_SUCCESS == result);
1920 }
1921 
testMultiplaneImages(Context & context,ImageTestParams params)1922 tcu::TestStatus testMultiplaneImages (Context& context, ImageTestParams params)
1923 {
1924 	const VkFormat multiplaneFormats[] =
1925 	{
1926 		VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
1927 		VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
1928 		VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
1929 		VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
1930 		VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM,
1931 		VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,
1932 		VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
1933 		VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,
1934 		VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
1935 		VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,
1936 		VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,
1937 		VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
1938 		VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,
1939 		VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
1940 		VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,
1941 		VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM,
1942 		VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,
1943 		VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM,
1944 		VK_FORMAT_G16_B16R16_2PLANE_422_UNORM
1945 	};
1946 
1947 	std::vector<VkImageCreateFlags> nonSparseCreateFlags
1948 	{
1949 		  VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
1950 		, VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT
1951 		, VK_IMAGE_CREATE_ALIAS_BIT
1952 		/* VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT - present tests use only one physical device */
1953 		, VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT
1954 		/* VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT not apply with planar formats */
1955 		, VK_IMAGE_CREATE_EXTENDED_USAGE_BIT
1956 		, VK_IMAGE_CREATE_DISJOINT_BIT
1957 		, VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT
1958 	};
1959 	if (context.getDeviceVulkan11Features().protectedMemory)
1960 	{
1961 		nonSparseCreateFlags.emplace_back(VK_IMAGE_CREATE_PROTECTED_BIT);
1962 	}
1963 #ifndef CTS_USES_VULKANSC
1964 	std::vector<VkImageCreateFlags> nonSparseCreateFlagsNoSC;
1965 	if (context.isDeviceFunctionalitySupported(VK_NV_CORNER_SAMPLED_IMAGE_EXTENSION_NAME))
1966 	{
1967 		nonSparseCreateFlagsNoSC.push_back(VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV);
1968 	}
1969 	if (context.isDeviceFunctionalitySupported(VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME))
1970 	{
1971 		nonSparseCreateFlagsNoSC.push_back(VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT);
1972 	}
1973 	if (context.isDeviceFunctionalitySupported(VK_EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME))
1974 	{
1975 		nonSparseCreateFlagsNoSC.push_back(VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT);
1976 	}
1977 	if (context.isDeviceFunctionalitySupported(VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME))
1978 	{
1979 		nonSparseCreateFlagsNoSC.push_back(VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_QCOM);
1980 	}
1981 
1982 	auto isMultisampledRenderToSingleSampledEnabled = [&]() -> bool
1983 	{
1984 		bool enabled = false;
1985 		if (context.isDeviceFunctionalitySupported(VK_EXT_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_EXTENSION_NAME))
1986 		{
1987 			const auto& feature = context.getMultisampledRenderToSingleSampledFeaturesEXT();
1988 			enabled = feature.multisampledRenderToSingleSampled != VK_FALSE;
1989 		}
1990 		return enabled;
1991 	};
1992 	if (isMultisampledRenderToSingleSampledEnabled())
1993 		nonSparseCreateFlagsNoSC.push_back(VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT);
1994 	nonSparseCreateFlags.insert(nonSparseCreateFlags.end(), nonSparseCreateFlagsNoSC.begin(), nonSparseCreateFlagsNoSC.end());
1995 #endif // CTS_USES_VULKANSC
1996 
1997 	const std::vector<VkImageCreateFlags> sparseCreateFlags
1998 	{
1999 		VK_IMAGE_CREATE_SPARSE_BINDING_BIT,
2000 		VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,
2001 		VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,
2002 		VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
2003 	};
2004 
2005 	const bool								isSparseTest		((params.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) != 0);
2006 	const InstanceInterface&				vki					= context.getInstanceInterface();
2007 	const VkPhysicalDevice					physicalDevice		= context.getPhysicalDevice();
2008 	const DeviceInterface&					vk					= context.getDeviceInterface();
2009 	const VkDevice							device				= context.getDevice();
2010 	const VkImageUsageFlags					transientFlags		= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
2011 	const VkPhysicalDeviceMemoryProperties	memoryProperties	= getPhysicalDeviceMemoryProperties(vki, physicalDevice);
2012 	tcu::TestLog&							log					= context.getTestContext().getLog();
2013 	tcu::ResultCollector					result				(log, "ERROR: ");
2014 	std::set<VkFormat>						supportedFormats	{};
2015 
2016 	log << TestLog::Message << "Memory properties: " << memoryProperties << TestLog::EndMessage;
2017 
2018 	for (const VkFormat format : multiplaneFormats)
2019 	{
2020 		for (const VkImageCreateFlags loopCreateFlags : (isSparseTest ? sparseCreateFlags : nonSparseCreateFlags))
2021 		{
2022 			const VkImageType			imageType			= ((loopCreateFlags & VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT)
2023 #ifndef CTS_USES_VULKANSC
2024 																|| (loopCreateFlags & VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT)
2025 #endif // CTS_USES_VULKANSC
2026 																																	)
2027 																? isYCbCrConversionFormat(format)
2028 																  ? VK_IMAGE_TYPE_MAX_ENUM
2029 																  : VK_IMAGE_TYPE_3D
2030 																: VK_IMAGE_TYPE_2D;
2031 			if (imageType == VK_IMAGE_TYPE_MAX_ENUM) continue;
2032 
2033 			if ((loopCreateFlags & VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT) && !isDepthStencilFormat(format)) continue;
2034 
2035 			for (VkImageUsageFlags		loopUsageFlags	= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2036 										loopUsageFlags	<= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2037 										loopUsageFlags	= nextFlagExcluding(loopUsageFlags, transientFlags))
2038 			{
2039 				const VkImageCreateFlags	actualCreateFlags	= loopCreateFlags | (isSparseTest ? params.flags : 0);
2040 				const VkImageUsageFlags		actualUsageFlags	= loopUsageFlags  | (params.transient ? VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0);
2041 				const uint32_t				arrayLayers			= ((imageType == VK_IMAGE_TYPE_2D) && (loopCreateFlags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)) ? 6u : 1u;
2042 				const VkImageCreateInfo		imageInfo			=
2043 				{
2044 					VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType          sType;
2045 					DE_NULL,								// const void*              pNext;
2046 					actualCreateFlags,						// VkImageCreateFlags       flags;
2047 					imageType,								// VkImageType              imageType;
2048 					format,									// VkFormat                 format;
2049 					{ 64u, 64u, 1u, },						// VkExtent3D               extent;
2050 					1u,										// uint32_t                 mipLevels;
2051 					arrayLayers,							// uint32_t                 arrayLayers;
2052 					VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits    samples;
2053 					params.tiling,							// VkImageTiling            tiling;
2054 					actualUsageFlags,						// VkImageUsageFlags        usage;
2055 					VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode            sharingMode;
2056 					0u,										// uint32_t                 queueFamilyIndexCount;
2057 					DE_NULL,								// const uint32_t*          pQueueFamilyIndices;
2058 					VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout            initialLayout;
2059 				};
2060 
2061 				if (isMultiplaneImageSupported(vki, physicalDevice, imageInfo))
2062 				{
2063 					const Unique<VkImage>			image			((params.useMaint4) ? Move<VkImage>() : createImage(vk, device, &imageInfo));
2064 
2065 					log << tcu::TestLog::Message << "- " << getImageInfoString(imageInfo) << tcu::TestLog::EndMessage;
2066 
2067 					supportedFormats.insert(format);
2068 
2069 					for (deUint32 planeNdx = 0; planeNdx < (deUint32)getPlaneCount(format); planeNdx++)
2070 					{
2071 						VkMemoryRequirements2						requirements	=
2072 						{
2073 							VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
2074 							DE_NULL,
2075 							{ 0u, 0u, 0u }
2076 						};
2077 						const VkImageAspectFlagBits					aspect		= getPlaneAspect(planeNdx);
2078 
2079 	#ifndef CTS_USES_VULKANSC
2080 						if (params.useMaint4)
2081 						{
2082 							const VkDeviceImageMemoryRequirementsKHR	info	=
2083 							{
2084 								VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR,
2085 								DE_NULL,
2086 								&imageInfo,
2087 								aspect
2088 							};
2089 							vk.getDeviceImageMemoryRequirements(device, &info, &requirements);
2090 						}
2091 						else
2092 						{
2093 	#endif // CTS_USES_VULKANSC
2094 							const VkImagePlaneMemoryRequirementsInfo	aspectInfo	=
2095 							{
2096 								VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO,
2097 								DE_NULL,
2098 								aspect
2099 							};
2100 							const VkImageMemoryRequirementsInfo2		info		=
2101 							{
2102 								VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
2103 								(actualCreateFlags & VK_IMAGE_CREATE_DISJOINT_BIT) == 0 ? DE_NULL : &aspectInfo,
2104 								*image
2105 							};
2106 
2107 							vk.getImageMemoryRequirements2(device, &info, &requirements);
2108 	#ifndef CTS_USES_VULKANSC
2109 						}
2110 	#endif // CTS_USES_VULKANSC
2111 
2112 						log << TestLog::Message << "Aspect: " << getImageAspectFlagsStr(aspect) << ", Requirements: " << requirements << TestLog::EndMessage;
2113 
2114 						result.check(deIsPowerOfTwo64(static_cast<deUint64>(requirements.memoryRequirements.alignment)), "VkMemoryRequirements alignment isn't power of two");
2115 
2116 	#ifndef CTS_USES_VULKANSC
2117 						if (actualCreateFlags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)
2118 						{
2119 							std::vector<VkSparseImageMemoryRequirements> sparseRequirements;
2120 							if ((*image == DE_NULL) || params.useMaint4)
2121 								sparseRequirements = getDeviceImageSparseMemoryRequirements(vk, device, imageInfo, aspect);
2122 							else
2123 								sparseRequirements = getImageSparseMemoryRequirements(vk, device, *image);
2124 
2125 							for (const VkSparseImageMemoryRequirements& sr : sparseRequirements)
2126 							{
2127 								if (sr.formatProperties.aspectMask == aspect)
2128 								{
2129 									result.check((sr.imageMipTailSize % requirements.memoryRequirements.alignment) == 0,
2130 										"VkSparseImageMemoryRequirements::imageMipTailSize is not aligned with sparse block size");
2131 									break;
2132 								}
2133 							}
2134 						}
2135 	#endif // CTS_USES_VULKANSC
2136 
2137 						if (result.check(requirements.memoryRequirements.memoryTypeBits != 0, "No supported memory types"))
2138 						{
2139 							typedef std::vector<deUint32>::const_iterator	IndexIterator;
2140 							const std::vector<deUint32>						usedMemoryTypeIndices	= bitsToIndices(requirements.memoryRequirements.memoryTypeBits);
2141 							bool											hasHostVisibleType		= false;
2142 
2143 							for (IndexIterator memoryTypeNdx = usedMemoryTypeIndices.begin(); memoryTypeNdx != usedMemoryTypeIndices.end(); ++memoryTypeNdx)
2144 							{
2145 								if (result.check(*memoryTypeNdx < memoryProperties.memoryTypeCount, "Unknown memory type bits set in memory requirements"))
2146 								{
2147 									const VkMemoryPropertyFlags	propertyFlags	(memoryProperties.memoryTypes[*memoryTypeNdx].propertyFlags);
2148 
2149 									if (propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
2150 										hasHostVisibleType = true;
2151 
2152 									if (propertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
2153 									{
2154 										result.check((imageInfo.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0u,
2155 											"Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT for a non-transient attachment image");
2156 									}
2157 								}
2158 								else
2159 									break;
2160 							}
2161 
2162 							result.check(params.tiling != VK_IMAGE_TILING_LINEAR || (hasHostVisibleType || (loopCreateFlags & VK_IMAGE_CREATE_PROTECTED_BIT)),
2163 								"Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT");
2164 						}
2165 					}
2166 				}
2167 			}
2168 		}
2169 	}
2170 
2171 	if (supportedFormats.size() == 0)
2172 	{
2173 		return tcu::TestStatus(QP_TEST_RESULT_NOT_SUPPORTED,
2174 			"None of tested in given configuration multiplanar formats is supported by device.");
2175 	}
2176 
2177 	return tcu::TestStatus(result.getResult(), result.getMessage());
2178 }
2179 
checkSupportMultiplane(Context & context,ImageTestParams params)2180 void checkSupportMultiplane (Context& context, ImageTestParams params)
2181 {
2182 	checkSupportImageMemoryRequirementsOriginal(context, params);
2183 
2184 	context.requireDeviceFunctionality("VK_KHR_get_memory_requirements2");
2185 	context.requireDeviceFunctionality("VK_KHR_sampler_ycbcr_conversion");
2186 
2187 	if (params.useMaint4)
2188 		context.requireDeviceFunctionality("VK_KHR_maintenance4");
2189 }
2190 
populateMultiplaneTestGroup(tcu::TestCaseGroup * group,bool useMaint4)2191 void populateMultiplaneTestGroup (tcu::TestCaseGroup* group, bool useMaint4)
2192 {
2193 	const struct
2194 	{
2195 		VkImageCreateFlags		flags;
2196 		bool					transient;
2197 		const char* const		name;
2198 	} imageFlagsCases[] =
2199 	{
2200 		{ (VkImageCreateFlags)0,																								false,	"regular"					},
2201 		{ (VkImageCreateFlags)0,																								true,	"transient"					},
2202 		{ VK_IMAGE_CREATE_SPARSE_BINDING_BIT,																					false,	"sparse"					},
2203 		{ VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,											false,	"sparse_residency"			},
2204 		{ VK_IMAGE_CREATE_SPARSE_BINDING_BIT											| VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,	false,	"sparse_aliased"			},
2205 		{ VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT		| VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,	false,	"sparse_residency_aliased"	},
2206 	};
2207 	const struct
2208 	{
2209 		VkImageTiling	value;
2210 		const char*		name;
2211 	} tilings[] =
2212 	{
2213 		{ VK_IMAGE_TILING_OPTIMAL,	"optimal"	},
2214 		{ VK_IMAGE_TILING_LINEAR,	"linear"	}
2215 	};
2216 
2217 	for (size_t flagsNdx = 0; flagsNdx < DE_LENGTH_OF_ARRAY(imageFlagsCases); ++flagsNdx)
2218 	for (size_t tilingNdx = 0; tilingNdx < DE_LENGTH_OF_ARRAY(tilings); ++tilingNdx)
2219 	{
2220 		const VkImageCreateFlags	flags		= imageFlagsCases[flagsNdx].flags;
2221 		const bool					transient	= imageFlagsCases[flagsNdx].transient;
2222 		const VkImageTiling			tiling		= tilings[tilingNdx].value;
2223 		const ImageTestParams		params		(flags, tiling, transient, useMaint4);
2224 		const std::string			name		= std::string(imageFlagsCases[flagsNdx].name) + "_" + tilings[tilingNdx].name;
2225 
2226 		if (tiling == VK_IMAGE_TILING_LINEAR && (flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) != 0)
2227 			continue;
2228 
2229 		addFunctionCase(group, name, checkSupportMultiplane, testMultiplaneImages, params);
2230 	}
2231 }
2232 
testVkMemoryPropertyFlags(Context & context)2233 tcu::TestStatus testVkMemoryPropertyFlags(Context& context)
2234 {
2235 	VkMemoryPropertyFlags	propertyFlagSets[]	=
2236 	{
2237 		0,
2238 		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT	| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
2239 		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT	| VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
2240 		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT	| VK_MEMORY_PROPERTY_HOST_CACHED_BIT			| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
2241 		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
2242 		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT	| VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT			| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
2243 		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT	| VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT			| VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
2244 		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT	| VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT			| VK_MEMORY_PROPERTY_HOST_CACHED_BIT			| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
2245 		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT	| VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT,
2246 		VK_MEMORY_PROPERTY_PROTECTED_BIT,
2247 		VK_MEMORY_PROPERTY_PROTECTED_BIT	| VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
2248 #ifndef CTS_USES_VULKANSC
2249 		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT	| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT			| VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD,
2250 		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT	| VK_MEMORY_PROPERTY_HOST_CACHED_BIT			| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT			| VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD,
2251 		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT	| VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD,
2252 		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT	| VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT			| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT			| VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD,
2253 		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT	| VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT			| VK_MEMORY_PROPERTY_HOST_CACHED_BIT			| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT			| VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD,
2254 		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT	| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT			| VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD	| VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD,
2255 		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT	| VK_MEMORY_PROPERTY_HOST_CACHED_BIT			| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT			| VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD	| VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD,
2256 		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT	| VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD	| VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD,
2257 		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT	| VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT			| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT			| VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD	| VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD,
2258 		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT	| VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT			| VK_MEMORY_PROPERTY_HOST_CACHED_BIT			| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT			| VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD	| VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD,
2259 		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT	| VK_MEMORY_PROPERTY_RDMA_CAPABLE_BIT_NV
2260 #endif // CTS_USES_VULKANSC
2261 	};
2262 
2263 	const InstanceInterface&				vki					= context.getInstanceInterface();
2264 	const VkPhysicalDevice					physicalDevice		= context.getPhysicalDevice();
2265 	VkPhysicalDeviceMemoryProperties		memoryProperties;
2266 	uint32_t								matchingTypes		= 0;
2267 	tcu::TestLog&							log					= context.getTestContext().getLog();
2268 	tcu::ResultCollector					result				(log, "ERROR: ");
2269 
2270 	vki.getPhysicalDeviceMemoryProperties(physicalDevice, &memoryProperties);
2271 
2272 	for (uint32_t ndx = 0; ndx < memoryProperties.memoryTypeCount; ndx++)
2273 	{
2274 		for (auto& flag : propertyFlagSets)
2275 		{
2276 			if (memoryProperties.memoryTypes[ndx].propertyFlags == flag) matchingTypes++;
2277 		}
2278 	}
2279 
2280 	std::string								diffStr				= std::to_string(int(memoryProperties.memoryTypeCount - matchingTypes));
2281 
2282 	result.check(matchingTypes == memoryProperties.memoryTypeCount, "Unknown memory type bits set in memory requirements: " + diffStr + " mismatch");
2283 
2284 	return tcu::TestStatus(result.getResult(), result.getMessage());
2285 }
2286 
populateMemoryPropertyFlagsTestGroup(tcu::TestCaseGroup * group)2287 void populateMemoryPropertyFlagsTestGroup(tcu::TestCaseGroup* group)
2288 {
2289 	addFunctionCase(group, "check_all", testVkMemoryPropertyFlags);
2290 }
2291 
populateMultiplaneTestGroup(tcu::TestCaseGroup * group)2292 void populateMultiplaneTestGroup (tcu::TestCaseGroup* group)
2293 {
2294 	populateMultiplaneTestGroup(group, false);
2295 }
2296 
2297 
2298 #ifndef CTS_USES_VULKANSC
populateCreateInfoTestGroup(tcu::TestCaseGroup * group)2299 void populateCreateInfoTestGroup (tcu::TestCaseGroup* group)
2300 {
2301 	BufferMemoryRequirementsCreateInfo			bufferTest;
2302 	ImageMemoryRequirementsCreateInfo			imageTest;
2303 
2304 	bufferTest.populateTestGroup(group);
2305 	imageTest.populateTestGroup(group);
2306 
2307 	de::MovePtr<tcu::TestCaseGroup> multiplaneGroup(new tcu::TestCaseGroup(group->getTestContext(), "multiplane_image"));
2308 	populateMultiplaneTestGroup(multiplaneGroup.get(), true);
2309 	group->addChild(multiplaneGroup.release());
2310 }
2311 #endif // CTS_USES_VULKANSC
2312 
2313 } // anonymous
2314 
2315 
createRequirementsTests(tcu::TestContext & testCtx)2316 tcu::TestCaseGroup* createRequirementsTests (tcu::TestContext& testCtx)
2317 {
2318 	// Buffer and image memory requirements
2319 	de::MovePtr<tcu::TestCaseGroup> requirementsGroup(new tcu::TestCaseGroup(testCtx, "requirements"));
2320 
2321 	// Memory requirements tests with core functionality
2322 	requirementsGroup->addChild(createTestGroup(testCtx, "core", populateCoreTestGroup));
2323 	// Memory requirements tests with extension VK_KHR_get_memory_requirements2
2324 	requirementsGroup->addChild(createTestGroup(testCtx, "extended", populateExtendedTestGroup));
2325 	// Memory requirements tests with extension VK_KHR_dedicated_allocation
2326 	requirementsGroup->addChild(createTestGroup(testCtx, "dedicated_allocation", populateDedicatedAllocationTestGroup));
2327 	// Memory requirements tests with vkGetImagePlaneMemoryRequirements
2328 	requirementsGroup->addChild(createTestGroup(testCtx, "multiplane_image", populateMultiplaneTestGroup));
2329 	// Memory requirements tests with vkGetPhysicalDeviceMemoryProperties
2330 	requirementsGroup->addChild(createTestGroup(testCtx, "memory_property_flags", populateMemoryPropertyFlagsTestGroup));
2331 #ifndef CTS_USES_VULKANSC
2332 	// Memory requirements tests with extension VK_KHR_maintenance4
2333 	requirementsGroup->addChild(createTestGroup(testCtx, "create_info", populateCreateInfoTestGroup));
2334 #endif // CTS_USES_VULKANSC
2335 
2336 	return requirementsGroup.release();
2337 }
2338 
2339 } // memory
2340 } // vkt
2341