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