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