• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2021 The Khronos Group Inc.
6  * Copyright (c) 2016 The Android Open Source Project
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *	  http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22 * \brief Cover for non-zero of memoryTypeBits from vkGetBufferMemoryRequirements*() tests.
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktApiBufferMemoryRequirementsTests.hpp"
26 #include "vktApiBufferMemoryRequirementsTestsUtils.hpp"
27 #include "vktCustomInstancesDevices.hpp"
28 
29 #include "vkMemUtil.hpp"
30 #include "vkQueryUtil.hpp"
31 #include "vkTypeUtil.hpp"
32 #include "vkCmdUtil.hpp"
33 #include "vkObjUtil.hpp"
34 #include "deFilePath.hpp"
35 #include "tcuTestLog.hpp"
36 #include "tcuCommandLine.hpp"
37 
38 #include <algorithm>
39 #include <array>
40 #include <functional>
41 #include <iostream>
42 #include <set>
43 #include <sstream>
44 #include <tuple>
45 #include <vector>
46 
47 namespace vkt
48 {
49 namespace api
50 {
51 namespace
52 {
53 
54 using namespace de;
55 using namespace vk;
56 using namespace tcu;
57 
58 struct TestConfig;
59 struct InstanceConfig;
60 
61 enum BufferFateFlagBits
62 {
63 	Transfer		= 0x01,
64 	Storage			= 0x02,
65 	Other			= 0x04,
66 	AccStructure	= 0x08,
67 	Video			= 0x10
68 };
69 typedef deUint32	BufferFateFlags;
70 typedef typename std::add_pointer<typename std::add_const<char>::type>::type	cstr;
71 typedef u::BitsSet<BufferFateFlags, BufferFateFlagBits, cstr> BufferFateBits;
72 
73 const BufferFateBits	AvailableBufferFateBits
74 {
75 	std::make_tuple(Transfer,		"transfer_usage_bits"	),
76 	std::make_tuple(Storage,		"storage_usage_bits"	),
77 	std::make_tuple(Other,			"other_usage_bits"		),
78 	std::make_tuple(AccStructure,	"acc_struct_usage_bits"	),
79 	std::make_tuple(Video,			"video_usage_bits"		),
80 };
81 
82 typedef u::BitsSet<VkBufferCreateFlags, VkBufferCreateFlagBits, cstr>				BufferCreateBits;
83 typedef u::BitsSet<VkBufferUsageFlags, VkBufferUsageFlagBits, BufferFateFlagBits>	BufferUsageBits;
84 typedef u::BitsSet<VkExternalMemoryHandleTypeFlags,
85 					VkExternalMemoryHandleTypeFlagBits, cstr, bool>					ExternalMemoryHandleBits;
86 typedef SharedPtr<BufferCreateBits>			BufferCreateBitsPtr;
87 typedef SharedPtr<BufferUsageBits>			BufferUsageBitsPtr;
88 typedef SharedPtr<ExternalMemoryHandleBits>	ExternalMemoryHandleBitsPtr;
89 
90 struct TestConfig
91 {
92 	bool						useMethod2;
93 	SharedPtr<BufferCreateBits>	createBits;
94 	SharedPtr<BufferFateBits>	fateBits;
95 	bool						incExtMemTypeFlags;
96 	// Tests the buffer memory size requirement is less than or equal to the aligned size of the buffer.
97 	// Requires VK_KHR_maintenance4 extension.
98 	bool						testSizeRequirements;
99 };
100 struct InstanceConfig
101 {
102 	bool												useMethod2;
103 	SharedPtr<BufferCreateBits>							createBits;
104 	SharedPtr<BufferFateBits>							fateBits;
105 	SharedPtr<std::vector<BufferUsageBitsPtr>>			usageFlags;
106 	bool												incExtMemTypeFlags;
107 	SharedPtr<std::vector<ExternalMemoryHandleBitsPtr>>	extMemHandleFlags;
108 	bool												testSizeRequirements;
109 
InstanceConfigvkt::api::__anond1aac3cd0111::InstanceConfig110 	InstanceConfig(const TestConfig& conf)
111 		: useMethod2			(conf.useMethod2)
112 		, createBits			(conf.createBits)
113 		, fateBits				(conf.fateBits)
114 		, usageFlags			(new std::vector<SharedPtr<BufferUsageBits>>)
115 		, incExtMemTypeFlags	(conf.incExtMemTypeFlags)
116 		, extMemHandleFlags		(new std::vector<SharedPtr<ExternalMemoryHandleBits>>)
117 		, testSizeRequirements	(conf.testSizeRequirements) {}
118 };
119 
120 const BufferCreateBits	AvailableBufferCreateBits
121 {
122 	std::make_tuple( VkBufferCreateFlagBits(0),				"no_flags"				),
123 	std::make_tuple( VK_BUFFER_CREATE_PROTECTED_BIT,			"protected"			),
124 #ifndef CTS_USES_VULKANSC
125 	std::make_tuple( VK_BUFFER_CREATE_SPARSE_BINDING_BIT,		"sparse_binding"	),
126 	std::make_tuple( VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,	"sparse_residency"		),
127 	std::make_tuple( VK_BUFFER_CREATE_SPARSE_ALIASED_BIT,		"sparse_aliased"	),
128 #endif // CTS_USES_VULKANSC
129 };
130 
131 const BufferUsageBits	AvailableBufferUsageBits
132 {
133 	std::make_tuple( VK_BUFFER_USAGE_TRANSFER_SRC_BIT										, Transfer		),
134 	std::make_tuple( VK_BUFFER_USAGE_TRANSFER_DST_BIT										, Transfer		),
135 	std::make_tuple( VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT								, Storage		),
136 	std::make_tuple( VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT								, Storage		),
137 	std::make_tuple( VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT										, Storage		),
138 	std::make_tuple( VK_BUFFER_USAGE_STORAGE_BUFFER_BIT										, Storage		),
139 	std::make_tuple( VK_BUFFER_USAGE_INDEX_BUFFER_BIT										, Storage		),
140 	std::make_tuple( VK_BUFFER_USAGE_VERTEX_BUFFER_BIT										, Storage		),
141 	std::make_tuple( VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT									, Other			),
142 	std::make_tuple( VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT								, Other			),
143 #ifndef CTS_USES_VULKANSC
144 	std::make_tuple( VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR								, Video			),
145 	std::make_tuple( VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR								, Video			),
146 	std::make_tuple( VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT						, Other			),
147 	std::make_tuple( VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT				, Other			),
148 	std::make_tuple( VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT							, Other			),
149 	std::make_tuple( VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR	, AccStructure	),
150 	std::make_tuple( VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR					, AccStructure	),
151 	std::make_tuple( VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR							, AccStructure	),
152 	std::make_tuple( VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR								, Video			),
153 	std::make_tuple( VK_BUFFER_USAGE_VIDEO_ENCODE_SRC_BIT_KHR								, Video			),
154 #endif // CTS_USES_VULKANSC
155 };
156 
157 #define INTERNALTEST_EXTERNAL_MEMORY_HANDLE_TYPE_NO_BITS VkExternalMemoryHandleTypeFlagBits(0)
158 const ExternalMemoryHandleBits	AvailableExternalMemoryHandleBits
159 {
160 	std::make_tuple( INTERNALTEST_EXTERNAL_MEMORY_HANDLE_TYPE_NO_BITS						, "no_flags",			false ),
161 	std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT							, "opaque_fd",			false ),
162 	std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT						, "opaque_win32",		false ),
163 	std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT					, "opaque_win32_kmt",	false ),
164 	std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT						, "d3d11_tex",			false ),
165 	std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT					, "d3d11_tex_kmt",		false ),
166 	std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT							, "d3d12_heap",			false ),
167 	std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT						, "d3d12_rsrc",			false ),
168 	std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT							, "dma_buf",			false ),
169 #ifndef CTS_USES_VULKANSC
170 	std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID		, "android_hw",			false ),
171 #endif // CTS_USES_VULKANSC
172 	std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT					, "host_alloc",			true  ),
173 	std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT		, "host_mapped",		true  ),
174 #ifndef CTS_USES_VULKANSC
175 	std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA					, "zircon_vmo",			false ),
176 	std::make_tuple( VK_EXTERNAL_MEMORY_HANDLE_TYPE_RDMA_ADDRESS_BIT_NV						, "roma_addr",			false ),
177 #endif // CTS_USES_VULKANSC
178 };
179 
180 template<class Flag, class Bit, class Str, class... Ignored>
bitsToString(const u::BitsSet<Flag,Bit,Str,Ignored...> & bits,const std::string & prefix=std::string ())181 std::string bitsToString (const u::BitsSet<Flag, Bit, Str, Ignored...>& bits,
182 						  const std::string& prefix = std::string())
183 {
184 	DE_ASSERT(!bits.empty());
185 	std::stringstream s;
186 	s << prefix;
187 	bool atLeastOne = false;
188 	for (const auto& bit : bits) {
189 		if (atLeastOne) s << '_';
190 		s << std::get<1>(bit);
191 		atLeastOne = true;
192 	}
193 	return s.str();
194 }
195 
updateBufferCreateFlags(std::vector<BufferCreateBits> & flags)196 void updateBufferCreateFlags(std::vector<BufferCreateBits>& flags)
197 {
198 #ifndef CTS_USES_VULKANSC
199 	const auto&	residencyBit	= AvailableBufferCreateBits.get(VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT);
200 	const auto&	aliasedBit		= AvailableBufferCreateBits.get(VK_BUFFER_CREATE_SPARSE_ALIASED_BIT);
201 	const auto&	bindingBit		= AvailableBufferCreateBits.get(VK_BUFFER_CREATE_SPARSE_BINDING_BIT);
202 	const auto&	protectedBit	= AvailableBufferCreateBits.get(VK_BUFFER_CREATE_PROTECTED_BIT);
203 #endif // CTS_USES_VULKANSC
204 	const auto&	noneBit			= AvailableBufferCreateBits.get(VkBufferCreateFlagBits(0));
205 
206 #ifndef CTS_USES_VULKANSC
207 	// VUID-VkBufferCreateInfo-flags-00918 { if sparse residency or sparse aliased include sparse binding }
208 	for (auto& bits : flags)
209 	{
210 		if (bits.contains(residencyBit) || bits.contains(aliasedBit))
211 			bits.insert(bindingBit);
212 	}
213 
214 	// VUID-VkBufferCreateInfo-None-01888 { if sparse residency, sparse aliased or sparse binding then flags must not include protected }
215 	const typename BufferCreateBits::key_type disallowdBits[] { residencyBit, aliasedBit, bindingBit };
216 	for (auto i = flags.begin(); i != flags.end();)
217 	{
218 		auto& bits = *i;
219 		if (bits.contains(protectedBit))
220 		{
221 			for (const auto& disallowdBit : disallowdBits)
222 			{
223 				auto find = bits.find(disallowdBit);
224 				if (find != bits.end())
225 					bits.erase(find);
226 			}
227 		}
228 		i = bits.empty() ? flags.erase(i) : std::next(i);
229 	}
230 #endif // CTS_USES_VULKANSC
231 
232 	// since 0 is a valid VkBufferCreateFlagBits flag then remove it flags where it exists along with other non-zero flags
233 	for (auto i = flags.begin(); i != flags.end(); ++i)
234 	{
235 		auto& bits = *i;
236 		auto find = bits.find(noneBit);
237 		if (find != bits.end() && bits.size() > 1)
238 		{
239 			bits.erase(find);
240 		}
241 	}
242 
243 	// remove duplicates
244 	for (auto i = flags.begin(); i != flags.end(); ++i)
245 	{
246 		for (auto j = std::next(i); j != flags.end();)
247 			j = (*i == *j) ? flags.erase(j) : std::next(j);
248 	}
249 }
250 
251 class BufferMemoryRequirementsInstance : public TestInstance
252 {
253 public:
BufferMemoryRequirementsInstance(Context & context,const InstanceConfig config)254 							BufferMemoryRequirementsInstance	(Context&				context,
255 																 const InstanceConfig	config)
256 								: TestInstance	(context)
257 								, m_config		(config) {}
258 
259 	virtual					~BufferMemoryRequirementsInstance	(void) override = default;
260 	virtual tcu::TestStatus	iterate								(void) override;
261 
262 	void						getBufferMemoryRequirements		(VkMemoryRequirements&	result,
263 																 const DeviceInterface&	vkd,
264 																 VkDevice				device,
265 																 VkBuffer				buffer) const;
266 	void						getBufferMemoryRequirements2	(VkMemoryRequirements&	result,
267 																 const DeviceInterface&	vkd,
268 																 VkDevice				device,
269 																 VkBuffer				buffer) const;
270 	typedef void (BufferMemoryRequirementsInstance::* Method)	(VkMemoryRequirements&	result,
271 																 const DeviceInterface&	intf,
272 																 VkDevice				device,
273 																 VkBuffer				buffer) const;
274 	template<class T, class... AddArgs>
275 						void*	chainVkStructure				(void*					pNext,
276 																 const AddArgs&...		addArgs) const;
277 private:
278 	void						logFailedSubtests				(const std::vector<BufferCreateBitsPtr>&			failCreateBits,
279 																 const std::vector<BufferUsageBitsPtr>&				failUsageBits,
280 																 const std::vector<ExternalMemoryHandleBitsPtr>&	failExtMemHandleBits) const;
281 	const InstanceConfig	m_config;
282 };
283 
284 class MemoryRequirementsTest : public TestCase
285 {
286 public:
MemoryRequirementsTest(TestContext & testCtx,const std::string & name,const TestConfig testConfig)287 							MemoryRequirementsTest	(TestContext&			testCtx,
288 													 const std::string&		name,
289 													 const TestConfig		testConfig)
290 								: TestCase		(testCtx, name, std::string())
291 								, m_testConfig	(testConfig)
292 								, m_instConfig	(testConfig) {}
293 
294 	virtual					~MemoryRequirementsTest	(void) override = default;
295 	virtual void			checkSupport			(Context&				context) const override;
createInstance(Context & context) const296 	virtual TestInstance*	createInstance			(Context&				context) const override
297 	{
298 		return new BufferMemoryRequirementsInstance(context, m_instConfig);
299 	}
300 
301 private:
302 	const TestConfig	m_testConfig;
303 	InstanceConfig		m_instConfig;
304 };
305 
306 struct Info
307 {
308 	enum Type {
309 		Create,
310 		Usage
311 	}					m_type;
312 	std::ostringstream	m_str;
313 	cstr				m_file;
314 	int					m_line;
Infovkt::api::__anond1aac3cd0111::Info315 	template<class Msg>	Info(Type type, const Msg& msg, cstr file, int line)
316 		: m_type(type), m_str(), m_file(file), m_line(line) { m_str << msg; }
operator <<(std::ostringstream & str,const Info & info)317 	friend std::ostringstream& operator<<(std::ostringstream& str, const Info& info) {
318 		switch (info.m_type) {
319 		case Create:
320 			str << "Create buffer with " << info.m_str.str() << " not supported by device at "
321 				<< de::FilePath(info.m_file).getBaseName() << ":" << info.m_line;
322 			break;
323 		case Usage:
324 			str << info.m_str.str() << " at "
325 				<< de::FilePath(info.m_file).getBaseName() << ":" << info.m_line;
326 			break;
327 		}
328 		return str;
329 	}
330 };
331 #define INFOCREATE(msg_) Info(Info::Create, (msg_), __FILE__, __LINE__)
332 #define INFOUSAGE(msg_) Info(Info::Usage, (msg_), __FILE__, __LINE__)
333 
334 #ifndef CTS_USES_VULKANSC
readVideoCodecOperationFlagsKHR(const InstanceInterface & vki,const VkPhysicalDevice & device)335 VkVideoCodecOperationFlagsKHR readVideoCodecOperationFlagsKHR (const InstanceInterface& vki, const VkPhysicalDevice& device)
336 {
337 	uint32_t	queueFamilyPropertyCount = 0;
338 	vki.getPhysicalDeviceQueueFamilyProperties2(device, &queueFamilyPropertyCount, nullptr);
339 	DE_ASSERT(queueFamilyPropertyCount);
340 
341 	std::vector<VkQueueFamilyVideoPropertiesKHR>	videoQueueFamilyProperties(
342 														queueFamilyPropertyCount,
343 														{
344 														   VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR,		// VkStructureType					sType
345 														   nullptr,													// void*							pNext
346 														   0														// VkVideoCodecOperationFlagsKHR	videoCodecOperations
347 														});
348 	std::vector<VkQueueFamilyProperties2>			queueFamilyProperties(
349 														queueFamilyPropertyCount,
350 														{
351 															VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,			// VkStructureType					sType
352 															nullptr,												// void*							pNext
353 															{}														// VkQueueFamilyProperties			queueFamilyProperties
354 														});
355 	for (auto begin = queueFamilyProperties.begin(), i = begin, end = queueFamilyProperties.end(); i != end; ++i)
356 	{
357 		i->pNext = &videoQueueFamilyProperties.data()[std::distance(begin, i)];
358 	}
359 
360 	vki.getPhysicalDeviceQueueFamilyProperties2(device, &queueFamilyPropertyCount, queueFamilyProperties.data());
361 
362 	VkVideoCodecOperationFlagsKHR	codecOperationFlags = VK_VIDEO_CODEC_OPERATION_NONE_KHR;
363 	for (const VkQueueFamilyVideoPropertiesKHR& props : videoQueueFamilyProperties)
364 	{
365 		codecOperationFlags |= props.videoCodecOperations;
366 	}
367 
368 	return codecOperationFlags;
369 }
370 #endif // CTS_USES_VULKANSC
371 
checkSupport(Context & context) const372 void MemoryRequirementsTest::checkSupport (Context& context) const
373 {
374 	const InstanceInterface&						intf				= context.getInstanceInterface();
375 	const VkPhysicalDevice							physDevice			= context.getPhysicalDevice();
376 	auto&											log					= context.getTestContext().getLog();
377 
378 	if (m_testConfig.useMethod2)
379 		context.requireDeviceFunctionality("VK_KHR_get_memory_requirements2");
380 
381 	VkPhysicalDeviceProtectedMemoryFeatures			protectedMemFeatures
382 	{
383 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,	// VkStructureType	sType;
384 		nullptr,															// void*			pNext;
385 		VK_FALSE															// VkBool32			protectedMemory;
386 	};
387 	VkPhysicalDeviceFeatures2						extFeatures
388 	{
389 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,					// VkStructureType			sType;
390 		&protectedMemFeatures,												// void*					pNext;
391 		{}																	// VkPhysicalDeviceFeatures	features;
392 	};
393 	intf.getPhysicalDeviceFeatures2(physDevice, &extFeatures);
394 
395 	const VkPhysicalDeviceFeatures&	features					= extFeatures.features;
396 	const VkBool32&					protectedMemFeatureEnabled	= protectedMemFeatures.protectedMemory;
397 
398 	// check the creating bits
399 	{
400 		std::ostringstream			str;
401 		bool		notSupported	= false;
402 		const auto& createBits		= *m_testConfig.createBits;
403 
404 		if (createBits.contains(VK_BUFFER_CREATE_SPARSE_BINDING_BIT) && (VK_FALSE == features.sparseBinding))
405 		{
406 			str << INFOCREATE(getBufferCreateFlagsStr(VK_BUFFER_CREATE_SPARSE_BINDING_BIT));
407 			notSupported = true;
408 		}
409 		if (createBits.contains(VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) && (VK_FALSE == features.sparseResidencyBuffer))
410 		{
411 			if (notSupported) str << std::endl;
412 			str << INFOCREATE(getBufferCreateFlagsStr(VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT));
413 			notSupported = true;
414 		}
415 		if (createBits.contains(VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) && (VK_FALSE == features.sparseResidencyAliased))
416 		{
417 			if (notSupported) str << std::endl;
418 			str << INFOCREATE(getBufferCreateFlagsStr(VK_BUFFER_CREATE_SPARSE_ALIASED_BIT));
419 			notSupported = true;
420 		}
421 		if (createBits.contains(VK_BUFFER_CREATE_PROTECTED_BIT) && (VK_FALSE == protectedMemFeatureEnabled))
422 		{
423 			if (notSupported) str << std::endl;
424 			str << INFOCREATE(getBufferCreateFlagsStr(VK_BUFFER_CREATE_PROTECTED_BIT));
425 			notSupported = true;
426 		}
427 		if (notSupported)
428 		{
429 			log << tcu::TestLog::Message << str.str() << tcu::TestLog::EndMessage;
430 			TCU_THROW(NotSupportedError, "One or more create buffer flags not supported by device (check log for details)");
431 		}
432 	}
433 
434 	// check the usage bits and build instance input
435 	{
436 		std::vector<BufferUsageBits>	usageFlags;
437 		for (const auto& bit : *m_testConfig.fateBits)
438 		{
439 			auto fate = m_testConfig.fateBits->extract(bit);
440 			std::vector<VkBufferUsageFlags>		usageHints;
441 			std::vector<BufferUsageBits>		usageFlagsTmp;
442 			u::combine(usageFlagsTmp, AvailableBufferUsageBits.select<1>(fate), usageHints);
443 			u::mergeFlags(usageFlags, usageFlagsTmp);
444 		}
445 
446 		std::ostringstream str;
447 		std::array<bool, 7> msgs;
448 		bool notSupported	= false;
449 		int  entryCount		= 0;
450 		msgs.fill(false);
451 
452 		for (auto i = usageFlags.begin(); i != usageFlags.end();)
453 		{
454 			notSupported = false;
455 
456 #ifndef CTS_USES_VULKANSC
457 			if (i->any({VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR,
458 					   VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR, VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR})
459 					&& !context.isDeviceFunctionalitySupported("VK_KHR_acceleration_structure"))
460 			{
461 				if (!msgs[0])
462 				{
463 					if (entryCount++) str << std::endl;
464 					str << INFOUSAGE("VK_KHR_acceleration_structure not supported by device");
465 					msgs[0] = true;
466 				}
467 				notSupported = true;
468 			}
469 #endif // CTS_USES_VULKANSC
470 
471 			if (i->contains(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)
472 					&& !context.isBufferDeviceAddressSupported())
473 			{
474 				if (!msgs[1])
475 				{
476 					if (entryCount++) str << std::endl;
477 					str << INFOUSAGE("VK_EXT_buffer_device_address not supported by device");
478 					msgs[1] = true;
479 				}
480 				notSupported = true;
481 			}
482 
483 #ifndef CTS_USES_VULKANSC
484 			if (i->any({VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR, VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR,
485 					   VK_BUFFER_USAGE_VIDEO_ENCODE_SRC_BIT_KHR, VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR}))
486 			{
487 				if (!context.isDeviceFunctionalitySupported(VK_KHR_VIDEO_QUEUE_EXTENSION_NAME))
488 				{
489 					if (!msgs[2])
490 					{
491 						if (entryCount++) str << std::endl;
492 						str << INFOUSAGE("VK_EXT_video_queue not supported by device");
493 						msgs[2] = true;
494 					}
495 					notSupported = true;
496 				}
497 				else
498 				{
499 					const VkVideoCodecOperationFlagsKHR videoFlags = readVideoCodecOperationFlagsKHR(intf, physDevice);
500 
501 					if (i->any({VK_BUFFER_USAGE_VIDEO_ENCODE_SRC_BIT_KHR, VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR}))
502 					{
503 						if (!context.isDeviceFunctionalitySupported(VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME))
504 						{
505 							if (!msgs[3])
506 							{
507 								if (entryCount++) str << std::endl;
508 								str << INFOUSAGE("VK_EXT_video_encode_h264 not supported by device");
509 								msgs[3] = true;
510 							}
511 							notSupported = true;
512 						}
513 						if (!(videoFlags & VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT))
514 						{
515 							if (!msgs[4])
516 							{
517 								if (entryCount++) str << std::endl;
518 								str << INFOUSAGE("Could not find a queue that supports VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT on device");
519 								msgs[4] = true;
520 							}
521 							notSupported = true;
522 						}
523 					}
524 					if (i->any({VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR, VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR}))
525 					{
526 						if (!context.isDeviceFunctionalitySupported(VK_KHR_VIDEO_DECODE_H264_EXTENSION_NAME))
527 						{
528 							if (!msgs[5])
529 							{
530 								if (entryCount++) str << std::endl;
531 								str << INFOUSAGE("VK_KHR_video_decode_h264 not supported by device");
532 								msgs[5] = true;
533 							}
534 							notSupported = true;
535 						}
536 						if (!(videoFlags & VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR))
537 						{
538 							if (!msgs[6])
539 							{
540 								if (entryCount++) str << std::endl;
541 								str << INFOUSAGE("Could not find a queue that supports VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR on device");
542 								msgs[6] = true;
543 							}
544 							notSupported = true;
545 						}
546 					}
547 				}
548 			}
549 #endif // CTS_USES_VULKANSC
550 
551 			i = notSupported ? usageFlags.erase(i) : std::next(i);
552 		}
553 
554 		// remove duplicates
555 		for (auto i = usageFlags.begin(); i != usageFlags.end(); ++i)
556 		{
557 			for (auto j = std::next(i); j != usageFlags.end();)
558 				j = (*i == *j) ? usageFlags.erase(j) : std::next(j);
559 		}
560 
561 		if (usageFlags.empty())
562 		{
563 			log << tcu::TestLog::Message << str.str() << tcu::TestLog::EndMessage;
564 			TCU_THROW(NotSupportedError, "One or more buffer usage flags not supported by device (check log for details)");
565 		}
566 		else
567 		{
568 			if (entryCount > 0)
569 			{
570 				log << tcu::TestLog::Message << str.str() << tcu::TestLog::EndMessage;
571 			}
572 			DE_ASSERT(m_instConfig.usageFlags.get());
573 			m_instConfig.usageFlags->resize(usageFlags.size());
574 			std::transform(usageFlags.begin(), usageFlags.end(), m_instConfig.usageFlags->begin(),
575 						   [](BufferUsageBits& bits){ return BufferUsageBits::makeShared(std::move(bits)); });
576 		}
577 	}
578 
579 	// check the external memory handle type bits and build instance input
580 	{
581 		std::vector<ExternalMemoryHandleBits>	extMemHandleFlags;
582 		if (m_testConfig.incExtMemTypeFlags)
583 			extMemHandleFlags.push_back({AvailableExternalMemoryHandleBits.get(INTERNALTEST_EXTERNAL_MEMORY_HANDLE_TYPE_NO_BITS)});
584 		else
585 		{
586 			std::vector<VkExternalMemoryHandleTypeFlags>	handleHints;
587 			std::vector<ExternalMemoryHandleBits>			handleFlagsTmp;
588 			u::combine(handleFlagsTmp, AvailableExternalMemoryHandleBits.select<2>(true), handleHints);
589 			u::mergeFlags(extMemHandleFlags, handleFlagsTmp);
590 		}
591 
592 		DE_ASSERT(m_instConfig.extMemHandleFlags.get());
593 		m_instConfig.extMemHandleFlags->resize(extMemHandleFlags.size());
594 		std::transform(extMemHandleFlags.begin(), extMemHandleFlags.end(), m_instConfig.extMemHandleFlags->begin(),
595 					   [](ExternalMemoryHandleBits& bits){ return ExternalMemoryHandleBits::makeShared(std::move(bits)); });
596 	}
597 
598 	if (m_testConfig.testSizeRequirements)
599 	{
600 		if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance4"))
601 			TCU_THROW(NotSupportedError, "VK_KHR_maintenance4 not supported");
602 	}
603 }
604 
logFailedSubtests(const std::vector<BufferCreateBitsPtr> & failCreateBits,const std::vector<BufferUsageBitsPtr> & failUsageBits,const std::vector<ExternalMemoryHandleBitsPtr> & failExtMemHandleBits) const605 void BufferMemoryRequirementsInstance::logFailedSubtests (const std::vector<BufferCreateBitsPtr>&			failCreateBits,
606 														  const std::vector<BufferUsageBitsPtr>&			failUsageBits,
607 														  const std::vector<ExternalMemoryHandleBitsPtr>&	failExtMemHandleBits) const
608 {
609 	const deUint32	flagCount	= deUint32(failCreateBits.size());
610 	TestLog&		log			= m_context.getTestContext().getLog();
611 	deUint32		entries		= 0;
612 
613 	DE_ASSERT(flagCount && flagCount == failUsageBits.size() && flagCount == failExtMemHandleBits.size());
614 
615 	log << TestLog::Section("Failed", "Failed subtests");
616 
617 	for (deUint32 i = 0; i < flagCount; ++i)
618 	{
619 		{
620 			log << TestLog::Section("VkBufferCreateFlags", "Buffer create flags");
621 			auto msg = log << TestLog::Message;
622 			entries = 0;
623 			for (const auto& createBit : *failCreateBits[i])
624 			{
625 				if (entries++) msg << " ";
626 				const VkBufferCreateFlags flags = BufferCreateBits::extract(createBit);
627 				if (flags == 0)
628 					msg << "0";
629 				else msg << getBufferCreateFlagsStr(flags);
630 			}
631 			msg << TestLog::EndMessage << TestLog::EndSection;
632 		}
633 
634 		{
635 			log << TestLog::Section("VkBufferUsageFlags", "Buffer usage flags");
636 			auto msg = log << TestLog::Message;
637 			entries = 0;
638 			for (const auto& usageBit : *failUsageBits[i])
639 			{
640 				if (entries++) msg << " ";
641 				msg << getBufferUsageFlagsStr(BufferUsageBits::extract(usageBit));
642 			}
643 			msg << TestLog::EndMessage << TestLog::EndSection;
644 		}
645 
646 		{
647 			log << TestLog::Section("VkExternalMemoryHandleTypeFlags", "External memory handle type flags");
648 			auto msg = log << TestLog::Message;
649 			entries = 0;
650 			for (const auto& extMemHandleTypeBit : *failExtMemHandleBits[i])
651 			{
652 				if (entries++) msg << " ";
653 				msg << getExternalMemoryHandleTypeFlagsStr(ExternalMemoryHandleBits::extract(extMemHandleTypeBit));
654 			}
655 			msg << TestLog::EndMessage << TestLog::EndSection;
656 		}
657 	}
658 
659 	log << TestLog::EndSection;
660 }
661 
getBufferMemoryRequirements2(VkMemoryRequirements & result,const DeviceInterface & vkd,VkDevice device,VkBuffer buffer) const662 void BufferMemoryRequirementsInstance::getBufferMemoryRequirements2	(VkMemoryRequirements&	result,
663 																	 const DeviceInterface&	vkd,
664 																	 VkDevice				device,
665 																	 VkBuffer				buffer) const
666 {
667 	VkMemoryDedicatedRequirements	dedicatedRequirements	=
668 	{
669 		VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,		// VkStructureType			sType;
670 		nullptr,												// const void*				pNext;
671 		VK_FALSE,												// VkBool32					prefersDedicatedAllocation
672 		VK_FALSE												// VkBool32					requiresDedicatedAllocation
673 	};
674 
675 	VkMemoryRequirements2			desiredRequirements		=
676 	{
677 		VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,				// VkStructureType			sType
678 		&dedicatedRequirements,									// void*					pNext
679 		result													// VkMemoryRequirements		memoryRequirements
680 	};
681 
682 	VkBufferMemoryRequirementsInfo2	requirementsInfo		=
683 	{
684 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,	// VkStructureType			sType
685 		nullptr,												// const void*				pNext
686 		buffer													// VkBuffer					buffer
687 	};
688 
689 	vkd.getBufferMemoryRequirements2(device, &requirementsInfo, &desiredRequirements);
690 
691 	result = desiredRequirements.memoryRequirements;
692 }
693 
getBufferMemoryRequirements(VkMemoryRequirements & result,const DeviceInterface & vkd,VkDevice device,VkBuffer buffer) const694 void BufferMemoryRequirementsInstance::getBufferMemoryRequirements	(VkMemoryRequirements&	result,
695 																	 const DeviceInterface&	vkd,
696 																	 VkDevice				device,
697 																	 VkBuffer				buffer) const
698 {
699 	vkd.getBufferMemoryRequirements(device, buffer, &result);
700 }
701 
702 template<> void*
chainVkStructure(void * pNext,const VkExternalMemoryHandleTypeFlags & handleTypes) const703 BufferMemoryRequirementsInstance::chainVkStructure<VkExternalMemoryBufferCreateInfo> (void* pNext, const VkExternalMemoryHandleTypeFlags& handleTypes) const
704 {
705 	static VkExternalMemoryBufferCreateInfo	memInfo{};
706 	memInfo.sType		= VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO;
707 	memInfo.pNext		= pNext;
708 	memInfo.handleTypes	= handleTypes;
709 
710 	return &memInfo;
711 }
712 
713 #ifndef CTS_USES_VULKANSC
chainVkStructure(void * pNext,const VkBufferUsageFlags & videoCodecUsage) const714 template<> void* BufferMemoryRequirementsInstance::chainVkStructure<VkVideoProfileListInfoKHR> (void* pNext, const VkBufferUsageFlags& videoCodecUsage) const
715 {
716 	const bool encode = (videoCodecUsage & VK_BUFFER_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) || (videoCodecUsage & VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR);
717 	const bool decode = (videoCodecUsage & VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR) || (videoCodecUsage & VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR);
718 
719 	static VkVideoEncodeH264ProfileInfoEXT	encodeProfile
720 	{
721 		VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_INFO_EXT,	// VkStructureType						sType;
722 		nullptr,												// const void*							pNext;
723 		STD_VIDEO_H264_PROFILE_IDC_BASELINE						// StdVideoH264ProfileIdc				stdProfileIdc;
724 	};
725 
726 	static VkVideoDecodeH264ProfileInfoKHR	decodeProfile
727 	{
728 		VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR,	// VkStructureType						sType;
729 		nullptr,												// const void*							pNext;
730 		STD_VIDEO_H264_PROFILE_IDC_BASELINE,					// StdVideoH264ProfileIdc				stdProfileIdc;
731 		VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_KHR		// VkVideoDecodeH264FieldLayoutFlagsEXT	fieldLayout;
732 	};
733 
734 	static const VkVideoProfileInfoKHR	videoProfiles[]
735 	{
736 		// encode profile
737 		{
738 			VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR,			// VkStructureType						sType;
739 			&encodeProfile,										// void*								pNext;
740 			VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT,		// VkVideoCodecOperationFlagBitsKHR		videoCodecOperation;
741 			VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR,		// VkVideoChromaSubsamplingFlagsKHR		chromaSubsampling;
742 			VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR,				// VkVideoComponentBitDepthFlagsKHR		lumaBitDepth;
743 			VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR				// VkVideoComponentBitDepthFlagsKHR		chromaBitDepth;
744 		},
745 		// decode profile
746 		{
747 			VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR,			// VkStructureType						sType;
748 			&decodeProfile,										// void*								pNext;
749 			VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR,		// VkVideoCodecOperationFlagBitsKHR		videoCodecOperation;
750 			VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR,		// VkVideoChromaSubsamplingFlagsKHR		chromaSubsampling;
751 			VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR,				// VkVideoComponentBitDepthFlagsKHR		lumaBitDepth;
752 			VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR				// VkVideoComponentBitDepthFlagsKHR		chromaBitDepth;
753 		}
754 	};
755 	static VkVideoProfileListInfoKHR	profiles;
756 	profiles.sType			= VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR;
757 	profiles.pNext			= pNext;
758 	if (encode && decode)
759 	{
760 		profiles.profileCount	= 2u;
761 		profiles.pProfiles		= videoProfiles;
762 	}
763 	else if (encode)
764 	{
765 		profiles.profileCount	= 1u;
766 		profiles.pProfiles		= &videoProfiles[0];
767 	}
768 	else
769 	{
770 		profiles.profileCount	= 1u;
771 		profiles.pProfiles		= &videoProfiles[1];
772 	}
773 	return &profiles;
774 }
775 #endif // CTS_USES_VULKANSC
776 
createProtectedDevice(const Context & context)777 static Move<VkDevice> createProtectedDevice(const Context &context)
778 {
779 	auto &cmdLine = context.getTestContext().getCommandLine();
780 	const float queuePriority = 1.0f;
781 
782 	VkPhysicalDeviceProtectedMemoryFeatures protectedMemoryFeatures;
783 	protectedMemoryFeatures.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES;
784 	protectedMemoryFeatures.pNext = DE_NULL;
785 	protectedMemoryFeatures.protectedMemory = VK_TRUE;
786 
787 	VkDeviceQueueCreateInfo queueInfo =
788 	{
789 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	// VkStructureType			sType;
790 		DE_NULL,									// const void*				pNext;
791 		vk::VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,	// VkDeviceQueueCreateFlags	flags;
792 		context.getUniversalQueueFamilyIndex(),		// deUint32					queueFamilyIndex;
793 		1u,											// deUint32					queueCount;
794 		&queuePriority								// const float*				pQueuePriorities;
795 	};
796 	const VkDeviceCreateInfo deviceInfo =
797 	{
798 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,	// VkStructureType					sType;
799 		&protectedMemoryFeatures,				// const void*						pNext;
800 		(VkDeviceCreateFlags)0,					// VkDeviceCreateFlags				flags;
801 		1u,										// uint32_t							queueCreateInfoCount;
802 		&queueInfo,								// const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
803 		0u,										// uint32_t							enabledLayerCount;
804 		DE_NULL,								// const char* const*				ppEnabledLayerNames;
805 		0u,										// uint32_t							enabledExtensionCount;
806 		DE_NULL,								// const char* const*				ppEnabledExtensionNames;
807 		DE_NULL									// const VkPhysicalDeviceFeatures*	pEnabledFeatures;
808 	};
809 	return createCustomDevice(cmdLine.isValidationEnabled(), context.getPlatformInterface(), context.getInstance(), context.getInstanceInterface(), context.getPhysicalDevice(), &deviceInfo);
810 }
811 
iterate(void)812 TestStatus	BufferMemoryRequirementsInstance::iterate (void)
813 {
814 	const DeviceInterface&							vkd					= m_context.getDeviceInterface();
815 	const deUint32									queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
816 	const Method									method				= m_config.useMethod2
817 																			? &BufferMemoryRequirementsInstance::getBufferMemoryRequirements2
818 																			: &BufferMemoryRequirementsInstance::getBufferMemoryRequirements;
819 
820 	deUint32										passCount			= 0;
821 	deUint32										failCount			= 0;
822 	std::vector<BufferCreateBitsPtr>				failCreateBits;
823 	std::vector<BufferUsageBitsPtr>					failUsageBits;
824 	std::vector<ExternalMemoryHandleBitsPtr>		failExtMemHandleBits;
825 
826 	Move<VkDevice> protectedDevice;
827 	VkDevice device;
828 	if (m_config.createBits->contains(VK_BUFFER_CREATE_PROTECTED_BIT))
829 	{
830 		protectedDevice = createProtectedDevice(m_context);
831 		device = *protectedDevice;
832 	}
833 	else
834 	{
835 		device = m_context.getDevice();
836 	}
837 
838 	DE_ASSERT(!m_config.createBits->empty());
839 	const VkBufferCreateFlags infoCreateFlags = *m_config.createBits;
840 	{
841 		DE_ASSERT(!m_config.usageFlags->empty());
842 		for (auto u = m_config.usageFlags->cbegin(); u != m_config.usageFlags->cend(); ++u)
843 		{
844 			const VkBufferUsageFlags infoUsageFlags = *(u->get());
845 
846 			DE_ASSERT(!m_config.extMemHandleFlags->empty());
847 			for (auto m = m_config.extMemHandleFlags->cbegin(); m != m_config.extMemHandleFlags->cend(); ++m)
848 			{
849 				const VkExternalMemoryHandleTypeFlags handleFlags = *(m->get());
850 
851 				void* pNext = nullptr;
852 
853 #ifndef CTS_USES_VULKANSC
854 				if (m_config.fateBits->contains(BufferFateFlagBits::Video))
855 				{
856 					pNext = chainVkStructure<VkVideoProfileListInfoKHR>(pNext, infoUsageFlags);
857 				}
858 #endif // CTS_USES_VULKANSC
859 				if (m_config.incExtMemTypeFlags)
860 				{
861 					pNext = chainVkStructure<VkExternalMemoryBufferCreateInfo>(pNext, handleFlags);
862 				}
863 				VkBufferCreateInfo	createInfo
864 				{
865 					VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,					// VkStructureType					sType;
866 					pNext,													// const void*						pNext;
867 					infoCreateFlags,										// VkBufferCreateFlags				flags;
868 					4096u,													// VkDeviceSize						size;
869 					infoUsageFlags,											// VkBufferUsageFlags				usage;
870 					VK_SHARING_MODE_EXCLUSIVE,								// VkSharingMode					sharingMode;
871 					1u,														// uint32_t							queueFamilyIndexCount;
872 					&queueFamilyIndex,										// const uint32_t*					pQueueFamilyIndices;
873 				};
874 
875 #ifndef CTS_USES_VULKANSC
876 				if (m_config.testSizeRequirements)
877 				{
878 					VkPhysicalDeviceMaintenance4PropertiesKHR	maintenance4Properties		=
879 					{
880 						VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR,	// VkStructureType	sType;
881 						DE_NULL,														// void*			pNext;
882 						0u																// VkDeviceSize		maxBufferSize;
883 					};
884 
885 					VkPhysicalDeviceProperties2					physicalDeviceProperties2	=
886 					{
887 						VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,	// VkStructureType				sType;
888 						&maintenance4Properties,						// void*						pNext;
889 						{},												// VkPhysicalDeviceProperties	properties;
890 					};
891 
892 					m_context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &physicalDeviceProperties2);
893 
894 					const VkDeviceSize							maxBufferSize				= maintenance4Properties.maxBufferSize;
895 					DE_ASSERT(maxBufferSize > 0);
896 					VkDeviceSize								N							= 0;
897 
898 					while ((1ull << N) + 1 < maxBufferSize)
899 					{
900 						createInfo.size = (1ull << N) + 1;
901 
902 						try
903 						{
904 							Move<VkBuffer> buffer = createBuffer(vkd, device, &createInfo);
905 
906 							VkMemoryRequirements reqs{};
907 							(this->*method)(reqs, vkd, device, *buffer);
908 
909 							if (reqs.size <= static_cast<VkDeviceSize>(deAlign64(static_cast<deInt64>(createInfo.size), static_cast<deInt64>(reqs.alignment))))
910 							{
911 								++passCount;
912 							} else
913 							{
914 								++failCount;
915 								failCreateBits.emplace_back(m_config.createBits);
916 								failUsageBits.emplace_back(*u);
917 								failExtMemHandleBits.emplace_back(*m);
918 							}
919 
920 							N++;
921 						}
922 						catch (const vk::OutOfMemoryError&)
923 						{
924 							break;
925 						}
926 					}
927 
928 					if (m_context.getTestContext().getWatchDog())
929 						qpWatchDog_reset(m_context.getTestContext().getWatchDog());
930 				}
931 				else
932 #endif // CTS_USES_VULKANSC
933 				{
934 					Move<VkBuffer> buffer = createBuffer(vkd, device, &createInfo);
935 
936 					VkMemoryRequirements reqs{};
937 					(this->*method)(reqs, vkd, device, *buffer);
938 					if (reqs.memoryTypeBits)
939 						++passCount;
940 					else
941 					{
942 						++failCount;
943 						failCreateBits.emplace_back(m_config.createBits);
944 						failUsageBits.emplace_back(*u);
945 						failExtMemHandleBits.emplace_back(*m);
946 					}
947 				}
948 			}
949 		}
950 	}
951 
952 	if (failCount)
953 	{
954 		logFailedSubtests(failCreateBits, failUsageBits, failExtMemHandleBits);
955 		return TestStatus::fail(std::to_string(failCount));
956 	}
957 
958 	return TestStatus::pass(std::to_string(passCount));
959 }
960 
961 } // unnamed namespace
962 
createBufferMemoryRequirementsTests(tcu::TestContext & testCtx)963 tcu::TestCaseGroup* createBufferMemoryRequirementsTests (tcu::TestContext& testCtx)
964 {
965 	cstr nilstr = "";
966 
967 	struct
968 	{
969 		bool		include;
970 		cstr		name;
971 	} const extMemTypeFlags[] { { false, "ext_mem_flags_excluded" }, { true, "ext_mem_flags_included" } };
972 
973 	struct
974 	{
975 		bool		method;
976 		cstr		name;
977 	} const methods[]
978 	{
979 		{ false, "method1" },
980 		{ true, "method2" }
981 	};
982 
983 	std::vector<SharedPtr<BufferCreateBits>>	createBitPtrs;
984 	{
985 		std::vector<VkBufferCreateFlags>		hints;
986 		std::vector<BufferCreateBits>			createFlags;
987 		u::combine(createFlags,	AvailableBufferCreateBits, hints);
988 		updateBufferCreateFlags(createFlags);
989 		createBitPtrs.resize(createFlags.size());
990 		std::transform(createFlags.begin(), createFlags.end(), createBitPtrs.begin(),
991 					   [](BufferCreateBits& bits) { return BufferCreateBits::makeShared(std::move(bits)); });
992 	}
993 
994 	std::vector<SharedPtr<BufferFateBits>>	fateBitPtrs;
995 	{
996 		// An excerpt above has been disabled consciously for the sake of computational complexity.
997 		// Enabled block does the same things sequentially, it doesn't create cartesian product of combination of bits.
998 #if 0
999 		std::vector<BufferFateFlags>	hints;
1000 		std::vector<BufferFateBits>		bufferFateFlags;
1001 		u::combine(bufferFateFlags, AvailableBufferFateBits, hints);
1002 		fateBitPtrs.resize(bufferFateFlags.size());
1003 		std::transform(bufferFateFlags.begin(), bufferFateFlags.end(), fateBitPtrs.begin(),
1004 					   [](BufferFateBits& bits) { return BufferFateBits::makeShared(std::move(bits)); });
1005 #else
1006 		fateBitPtrs.resize(AvailableBufferFateBits.size());
1007 		std::transform(AvailableBufferFateBits.begin(), AvailableBufferFateBits.end(), fateBitPtrs.begin(),
1008 					   [](const typename BufferFateBits::value_type& bit) { return BufferFateBits::makeShared(bit); });
1009 #endif
1010 	}
1011 
1012 	auto groupRoot = new TestCaseGroup(testCtx, "buffer_memory_requirements", "vkGetBufferMemoryRequirements*(...) routines tests.");
1013 	for (const auto& createBits : createBitPtrs)
1014 	{
1015 		auto groupCreate = new TestCaseGroup(testCtx, bitsToString(*createBits, "create_").c_str(), nilstr);
1016 		for (const auto& extMemTypeFlag : extMemTypeFlags)
1017 		{
1018 			auto groupExtMemTypeFlags = new TestCaseGroup(testCtx, extMemTypeFlag.name, nilstr);
1019 			for (const auto& method : methods)
1020 			{
1021 				auto groupMethod = new TestCaseGroup(testCtx, method.name, nilstr);
1022 				for (const auto& fateBits : fateBitPtrs)
1023 				{
1024 #ifndef CTS_USES_VULKANSC
1025 					for (const auto testSizeReq : {false, true})
1026 #else
1027 					const bool testSizeReq = false;
1028 #endif // CTS_USES_VULKANSC
1029 					{
1030 						TestConfig	config;
1031 						config.fateBits				= fateBits;
1032 						config.incExtMemTypeFlags	= extMemTypeFlag.include;
1033 						config.createBits			= createBits;
1034 						config.useMethod2			= method.method;
1035 						config.testSizeRequirements	= testSizeReq;
1036 						groupMethod->addChild(new MemoryRequirementsTest(testCtx, ((testSizeReq ? "size_req_" : "") + bitsToString(*fateBits)).c_str(), config));
1037 					}
1038 				}
1039 				groupExtMemTypeFlags->addChild(groupMethod);
1040 			}
1041 			groupCreate->addChild(groupExtMemTypeFlags);
1042 		}
1043 		groupRoot->addChild(groupCreate);
1044 	}
1045 
1046 	return groupRoot;
1047 }
1048 } // api
1049 } // vkt
1050