/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2021 The Khronos Group Inc.
 * Copyright (c) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *	  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
* \brief Cover for non-zero of memoryTypeBits from vkGetBufferMemoryRequirements*() tests.
 *//*--------------------------------------------------------------------*/

#include "vktApiBufferMemoryRequirementsTests.hpp"
#include "vktApiBufferMemoryRequirementsTestsUtils.hpp"

#include "vkMemUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"
#include "deFilePath.hpp"
#include "tcuTestLog.hpp"

#include <algorithm>
#include <array>
#include <functional>
#include <iostream>
#include <set>
#include <sstream>
#include <tuple>
#include <vector>

namespace vkt
{
namespace api
{
namespace
{

using namespace de;
using namespace vk;
using namespace tcu;

struct TestConfig;
struct InstanceConfig;

enum BufferFateFlagBits
{
	Transfer		= 0x01,
	Storage			= 0x02,
	Other			= 0x04,
	AccStructure	= 0x08,
	Video			= 0x10
};
typedef deUint32	BufferFateFlags;
typedef typename std::add_pointer<typename std::add_const<char>::type>::type	cstr;
typedef u::BitsSet<BufferFateFlags, BufferFateFlagBits, cstr> BufferFateBits;

const BufferFateBits	AvailableBufferFateBits
{
	std::make_tuple(Transfer,		"transfer_usage_bits"	),
	std::make_tuple(Storage,		"storage_usage_bits"	),
	std::make_tuple(Other,			"other_usage_bits"		),
	std::make_tuple(AccStructure,	"acc_struct_usage_bits"	),
	std::make_tuple(Video,			"video_usage_bits"		),
};

typedef u::BitsSet<VkBufferCreateFlags, VkBufferCreateFlagBits, cstr>				BufferCreateBits;
typedef u::BitsSet<VkBufferUsageFlags, VkBufferUsageFlagBits, BufferFateFlagBits>	BufferUsageBits;
typedef u::BitsSet<VkExternalMemoryHandleTypeFlags,
					VkExternalMemoryHandleTypeFlagBits, cstr, bool>					ExternalMemoryHandleBits;
typedef SharedPtr<BufferCreateBits>			BufferCreateBitsPtr;
typedef SharedPtr<BufferUsageBits>			BufferUsageBitsPtr;
typedef SharedPtr<ExternalMemoryHandleBits>	ExternalMemoryHandleBitsPtr;

struct TestConfig
{
	bool						useMethod2;
	SharedPtr<BufferCreateBits>	createBits;
	SharedPtr<BufferFateBits>	fateBits;
	bool						incExtMemTypeFlags;
	// Tests the buffer memory size requirement is less than or equal to the aligned size of the buffer.
	// Requires VK_KHR_maintenance4 extension.
	bool						testSizeRequirements;
};
struct InstanceConfig
{
	bool												useMethod2;
	SharedPtr<BufferCreateBits>							createBits;
	SharedPtr<BufferFateBits>							fateBits;
	SharedPtr<std::vector<BufferUsageBitsPtr>>			usageFlags;
	bool												incExtMemTypeFlags;
	SharedPtr<std::vector<ExternalMemoryHandleBitsPtr>>	extMemHandleFlags;
	bool												testSizeRequirements;

	InstanceConfig(const TestConfig& conf)
		: useMethod2			(conf.useMethod2)
		, createBits			(conf.createBits)
		, fateBits				(conf.fateBits)
		, usageFlags			(new std::vector<SharedPtr<BufferUsageBits>>)
		, incExtMemTypeFlags	(conf.incExtMemTypeFlags)
		, extMemHandleFlags		(new std::vector<SharedPtr<ExternalMemoryHandleBits>>)
		, testSizeRequirements	(conf.testSizeRequirements) {}
};

const BufferCreateBits	AvailableBufferCreateBits
{
	std::make_tuple(VkBufferCreateFlagBits(0),				"no_flags"			),
	std::make_tuple(VK_BUFFER_CREATE_PROTECTED_BIT,			"protected"			),
	std::make_tuple(VK_BUFFER_CREATE_SPARSE_BINDING_BIT,	"sparse_binding"	),
	std::make_tuple(VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,	"sparse_residency"	),
	std::make_tuple(VK_BUFFER_CREATE_SPARSE_ALIASED_BIT,	"sparse_aliased"	),
};

const BufferUsageBits	AvailableBufferUsageBits
{
	std::make_tuple(VK_BUFFER_USAGE_TRANSFER_SRC_BIT										, Transfer		),
	std::make_tuple(VK_BUFFER_USAGE_TRANSFER_DST_BIT										, Transfer		),
	std::make_tuple(VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT								, Storage		),
	std::make_tuple(VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT								, Storage		),
	std::make_tuple(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT										, Storage		),
	std::make_tuple(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT										, Storage		),
	std::make_tuple(VK_BUFFER_USAGE_INDEX_BUFFER_BIT										, Storage		),
	std::make_tuple(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT										, Storage		),
	std::make_tuple(VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT										, Other			),
	std::make_tuple(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT								, Other			),
	std::make_tuple(VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR								, Video			),
	std::make_tuple(VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR								, Video			),
	std::make_tuple(VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT						, Other			),
	std::make_tuple(VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT				, Other			),
	std::make_tuple(VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT							, Other			),
	std::make_tuple(VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR	, AccStructure	),
	std::make_tuple(VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR					, AccStructure	),
	std::make_tuple(VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR							, AccStructure	),
	std::make_tuple(VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR								, Video			),
	std::make_tuple(VK_BUFFER_USAGE_VIDEO_ENCODE_SRC_BIT_KHR								, Video			),
};

#define INTERNALTEST_EXTERNAL_MEMORY_HANDLE_TYPE_NO_BITS VkExternalMemoryHandleTypeFlagBits(0)
const ExternalMemoryHandleBits	AvailableExternalMemoryHandleBits
{
	std::make_tuple(INTERNALTEST_EXTERNAL_MEMORY_HANDLE_TYPE_NO_BITS					, "no_flags",			false ),
	std::make_tuple(VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT						, "opaque_fd",			false ),
	std::make_tuple(VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT						, "opaque_win32",		false ),
	std::make_tuple(VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT					, "opaque_win32_kmt",	false ),
	std::make_tuple(VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT					, "d3d11_tex",			false ),
	std::make_tuple(VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT				, "d3d11_tex_kmt",		false ),
	std::make_tuple(VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT						, "d3d12_heap",			false ),
	std::make_tuple(VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT					, "d3d12_rsrc",			false ),
	std::make_tuple(VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT						, "dma_buf",			false ),
	std::make_tuple(VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID	, "android_hw",			false ),
	std::make_tuple(VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT				, "host_alloc",			true  ),
	std::make_tuple(VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT	, "host_mapped",		true  ),
	std::make_tuple(VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA				, "zircon_vmo",			false ),
	std::make_tuple(VK_EXTERNAL_MEMORY_HANDLE_TYPE_RDMA_ADDRESS_BIT_NV					, "roma_addr",			false ),
};

template<class Flag, class Bit, class Str, class... Ignored>
std::string bitsToString (const u::BitsSet<Flag, Bit, Str, Ignored...>& bits,
						  const std::string& prefix = std::string())
{
	DE_ASSERT(!bits.empty());
	std::stringstream s;
	s << prefix;
	bool atLeastOne = false;
	for (const auto& bit : bits) {
		if (atLeastOne) s << '_';
		s << std::get<1>(bit);
		atLeastOne = true;
	}
	return s.str();
}

void updateBufferCreateFlags(std::vector<BufferCreateBits>& flags)
{
	const auto&	residencyBit	= AvailableBufferCreateBits.get(VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT);
	const auto&	aliasedBit		= AvailableBufferCreateBits.get(VK_BUFFER_CREATE_SPARSE_ALIASED_BIT);
	const auto&	bindingBit		= AvailableBufferCreateBits.get(VK_BUFFER_CREATE_SPARSE_BINDING_BIT);
	const auto&	protectedBit	= AvailableBufferCreateBits.get(VK_BUFFER_CREATE_PROTECTED_BIT);
	const auto&	noneBit			= AvailableBufferCreateBits.get(VkBufferCreateFlagBits(0));

	// VUID-VkBufferCreateInfo-flags-00918 { if sparse residency or sparse aliased include sparse binding }
	for (auto& bits : flags)
	{
		if (bits.contains(residencyBit) || bits.contains(aliasedBit))
			bits.insert(bindingBit);
	}

	// VUID-VkBufferCreateInfo-None-01888 { if sparse residency, sparse aliased or sparse binding then flags must not include protected }
	const typename BufferCreateBits::key_type disallowdBits[] { residencyBit, aliasedBit, bindingBit };
	for (auto i = flags.begin(); i != flags.end();)
	{
		auto& bits = *i;
		if (bits.contains(protectedBit))
		{
			for (const auto& disallowdBit : disallowdBits)
			{
				auto find = bits.find(disallowdBit);
				if (find != bits.end())
					bits.erase(find);
			}
		}
		i = bits.empty() ? flags.erase(i) : std::next(i);
	}

	// since 0 is a valid VkBufferCreateFlagBits flag then remove it flags where it exists along with other non-zero flags
	for (auto i = flags.begin(); i != flags.end(); ++i)
	{
		auto& bits = *i;
		auto find = bits.find(noneBit);
		if (find != bits.end() && bits.size() > 1)
		{
			bits.erase(find);
		}
	}

	// remove duplicates
	for (auto i = flags.begin(); i != flags.end(); ++i)
	{
		for (auto j = std::next(i); j != flags.end();)
			j = (*i == *j) ? flags.erase(j) : std::next(j);
	}
}

class BufferMemoryRequirementsInstance : public TestInstance
{
public:
							BufferMemoryRequirementsInstance	(Context&				context,
																 const InstanceConfig	config)
								: TestInstance	(context)
								, m_config		(config) {}

	virtual					~BufferMemoryRequirementsInstance	(void) override = default;
	virtual tcu::TestStatus	iterate								(void) override;

	void						getBufferMemoryRequirements		(VkMemoryRequirements&	result,
																 const DeviceInterface&	vkd,
																 VkDevice				device,
																 VkBuffer				buffer) const;
	void						getBufferMemoryRequirements2	(VkMemoryRequirements&	result,
																 const DeviceInterface&	vkd,
																 VkDevice				device,
																 VkBuffer				buffer) const;
	typedef void (BufferMemoryRequirementsInstance::* Method)	(VkMemoryRequirements&	result,
																 const DeviceInterface&	intf,
																 VkDevice				device,
																 VkBuffer				buffer) const;
	template<class T, class... AddArgs>
						void*	chainVkStructure				(void*					pNext,
																 const AddArgs&...		addArgs) const;
private:
	void						logFailedSubtests				(const std::vector<BufferCreateBitsPtr>&			failCreateBits,
																 const std::vector<BufferUsageBitsPtr>&				failUsageBits,
																 const std::vector<ExternalMemoryHandleBitsPtr>&	failExtMemHandleBits) const;
	const InstanceConfig	m_config;
};

class MemoryRequirementsTest : public TestCase
{
public:
							MemoryRequirementsTest	(TestContext&			testCtx,
													 const std::string&		name,
													 const TestConfig		testConfig)
								: TestCase		(testCtx, name, std::string())
								, m_testConfig	(testConfig)
								, m_instConfig	(testConfig) {}

	virtual					~MemoryRequirementsTest	(void) override = default;
	virtual void			checkSupport			(Context&				context) const override;
	virtual TestInstance*	createInstance			(Context&				context) const override
	{
		return new BufferMemoryRequirementsInstance(context, m_instConfig);
	}

private:
	const TestConfig	m_testConfig;
	InstanceConfig		m_instConfig;
};

struct Info
{
	enum Type {
		Create,
		Usage
	}					m_type;
	std::ostringstream	m_str;
	cstr				m_file;
	int					m_line;
	template<class Msg>	Info(Type type, const Msg& msg, cstr file, int line)
		: m_type(type), m_str(), m_file(file), m_line(line) { m_str << msg; }
	friend std::ostringstream& operator<<(std::ostringstream& str, const Info& info) {
		switch (info.m_type) {
		case Create:
			str << "  Info (Create buffer with " << info.m_str.str() << " not supported by device at "
				<< de::FilePath(info.m_file).getBaseName() << ":" << info.m_line << ")";
			break;
		case Usage:
			str << "  Info (Create buffer with " << info.m_str.str() << " not supported by device at "
				<< de::FilePath(info.m_file).getBaseName() << ":" << info.m_line << ")";
			break;
		}
		return str;
	}
};
#define INFOCREATE(msg_) Info(Info::Create, (msg_), __FILE__, __LINE__)
#define INFOUSAGE(msg_) Info(Info::Usage, (msg_), __FILE__, __LINE__)

#ifndef VK_KHR_VIDEO_QUEUE_EXTENSION_NAME
#define VK_KHR_VIDEO_QUEUE_EXTENSION_NAME "VK_KHR_video_queue"
#endif

#ifndef VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME
#define VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME "VK_EXT_video_encode_h264"
#endif

#ifndef VK_EXT_VIDEO_DECODE_H264_EXTENSION_NAME
#define VK_EXT_VIDEO_DECODE_H264_EXTENSION_NAME "VK_EXT_video_decode_h264"
#endif

VkVideoCodecOperationFlagsKHR readVideoCodecOperationFlagsKHR (const InstanceInterface& vki, const VkPhysicalDevice& device)
{
	uint32_t	queueFamilyPropertyCount = 0;
	vki.getPhysicalDeviceQueueFamilyProperties2(device, &queueFamilyPropertyCount, nullptr);
	DE_ASSERT(queueFamilyPropertyCount);

	std::vector<VkVideoQueueFamilyProperties2KHR>	videoQueueFamilyProperties(
														queueFamilyPropertyCount,
														{
														   VK_STRUCTURE_TYPE_VIDEO_QUEUE_FAMILY_PROPERTIES_2_KHR,	// VkStructureType					sType
														   nullptr,													// void*							pNext
														   0														// VkVideoCodecOperationFlagsKHR	videoCodecOperations
														});
	std::vector<VkQueueFamilyProperties2>			queueFamilyProperties(
														queueFamilyPropertyCount,
														{
															VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,			// VkStructureType					sType
															nullptr,												// void*							pNext
															{}														// VkQueueFamilyProperties			queueFamilyProperties
														});
	for (auto begin = queueFamilyProperties.begin(), i = begin, end = queueFamilyProperties.end(); i != end; ++i)
	{
		i->pNext = &videoQueueFamilyProperties.data()[std::distance(begin, i)];
	}

	vki.getPhysicalDeviceQueueFamilyProperties2(device, &queueFamilyPropertyCount, queueFamilyProperties.data());

	VkVideoCodecOperationFlagsKHR	codecOperationFlags = VK_VIDEO_CODEC_OPERATION_INVALID_BIT_KHR;
	for (const VkVideoQueueFamilyProperties2KHR& props : videoQueueFamilyProperties)
	{
		codecOperationFlags |= props.videoCodecOperations;
	}

	return codecOperationFlags;
}

void MemoryRequirementsTest::checkSupport (Context& context) const
{
	const InstanceInterface&						intf				= context.getInstanceInterface();
	const VkPhysicalDevice							physDevice			= context.getPhysicalDevice();

	if (m_testConfig.useMethod2)
		context.requireDeviceFunctionality(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);

	VkPhysicalDeviceProtectedMemoryFeatures			protectedMemFeatures
	{
		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,	// VkStructureType	sType;
		nullptr,															// void*			pNext;
		VK_FALSE															// VkBool32			protectedMemory;
	};
	VkPhysicalDeviceFeatures2						extFeatures
	{
		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,					// VkStructureType			sType;
		&protectedMemFeatures,												// void*					pNext;
		{}																	// VkPhysicalDeviceFeatures	features;
	};
	intf.getPhysicalDeviceFeatures2(physDevice, &extFeatures);

	const VkPhysicalDeviceFeatures&	features					= extFeatures.features;
	const VkBool32&					protectedMemFeatureEnabled	= protectedMemFeatures.protectedMemory;

	// check the creating bits
	{
		std::ostringstream			str;
		bool		notSupported	= false;
		const auto& createBits		= *m_testConfig.createBits;

		if (createBits.contains(VK_BUFFER_CREATE_SPARSE_BINDING_BIT) && (VK_FALSE == features.sparseBinding))
		{
			str << INFOCREATE(getBufferCreateFlagsStr(VK_BUFFER_CREATE_SPARSE_BINDING_BIT));
			notSupported = true;
		}
		if (createBits.contains(VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) && (VK_FALSE == features.sparseResidencyBuffer))
		{
			if (notSupported) str << std::endl;
			str << INFOCREATE(getBufferCreateFlagsStr(VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT));
			notSupported = true;
		}
		if (createBits.contains(VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) && (VK_FALSE == features.sparseResidencyAliased))
		{
			if (notSupported) str << std::endl;
			str << INFOCREATE(getBufferCreateFlagsStr(VK_BUFFER_CREATE_SPARSE_ALIASED_BIT));
			notSupported = true;
		}
		if (createBits.contains(VK_BUFFER_CREATE_PROTECTED_BIT) && (VK_FALSE == protectedMemFeatureEnabled))
		{
			if (notSupported) str << std::endl;
			str << INFOCREATE(getBufferCreateFlagsStr(VK_BUFFER_CREATE_PROTECTED_BIT));
			notSupported = true;
		}
		if (notSupported)
		{
			std::cout << str.str() << std::endl;
			TCU_THROW(NotSupportedError, "One or more create buffer flags not supported by device");
		}
	}

	// check the usage bits and build instance input
	{
		std::vector<BufferUsageBits>	usageFlags;
		for (const auto& bit : *m_testConfig.fateBits)
		{
			auto fate = m_testConfig.fateBits->extract(bit);
			std::vector<VkBufferUsageFlags>		usageHints;
			std::vector<BufferUsageBits>		usageFlagsTmp;
			u::combine(usageFlagsTmp, AvailableBufferUsageBits.select<1>(fate), usageHints);
			u::mergeFlags(usageFlags, usageFlagsTmp);
		}

		std::ostringstream str;
		std::array<bool, 7> msgs;
		bool notSupported	= false;
		int  entryCount		= 0;
		msgs.fill(false);

		for (auto i = usageFlags.begin(); i != usageFlags.end();)
		{
			notSupported = false;

			if (i->any({VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR,
					   VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR, VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR})
					&& !context.isDeviceFunctionalitySupported("VK_KHR_acceleration_structure"))
			{
				if (!msgs[0])
				{
					if (entryCount++) str << std::endl;
					str << INFOUSAGE("VK_KHR_acceleration_structure not supported by device");
					msgs[0] = true;
				}
				notSupported = true;
			}

			if (i->contains(VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT)
					&& !context.isBufferDeviceAddressSupported())
			{
				if (!msgs[1])
				{
					if (entryCount++) str << std::endl;
					str << INFOUSAGE("VK_EXT_buffer_device_address not supported by device");
					msgs[1] = true;
				}
				notSupported = true;
			}

			if (i->any({VK_BUFFER_USAGE_VIDEO_ENCODE_SRC_BIT_KHR, VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR,
						VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR, VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR}))
			{
				if (!context.isDeviceFunctionalitySupported(VK_KHR_VIDEO_QUEUE_EXTENSION_NAME))
				{
					if (!msgs[2])
					{
						if (entryCount++) str << std::endl;
						str << INFOUSAGE("VK_EXT_video_queue not supported by device");
						msgs[2] = true;
					}
					notSupported = true;
				}
				else
				{
					const VkVideoCodecOperationFlagsKHR videoFlags = readVideoCodecOperationFlagsKHR(intf, physDevice);

					if (i->any({VK_BUFFER_USAGE_VIDEO_ENCODE_SRC_BIT_KHR, VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR}))
					{
						if (!context.isDeviceFunctionalitySupported(VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME))
						{
							if (!msgs[3])
							{
								if (entryCount++) str << std::endl;
								str << INFOUSAGE("VK_EXT_video_encode_h264 not supported by device");
								msgs[3] = true;
							}
							notSupported = true;
						}
						if (!(videoFlags & VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT))
						{
							if (!msgs[4])
							{
								if (entryCount++) str << std::endl;
								str << INFOUSAGE("Could not find a queue that supports VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT on device");
								msgs[4] = true;
							}
							notSupported = true;
						}
					}
					if (i->any({VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR, VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR}))
					{
						if (!context.isDeviceFunctionalitySupported(VK_EXT_VIDEO_DECODE_H264_EXTENSION_NAME))
						{
							if (!msgs[5])
							{
								if (entryCount++) str << std::endl;
								str << INFOUSAGE("VK_EXT_video_decode_h264 not supported by device");
								msgs[5] = true;
							}
							notSupported = true;
						}
						if (!(videoFlags & VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_EXT))
						{
							if (!msgs[6])
							{
								if (entryCount++) str << std::endl;
								str << INFOUSAGE("Could not find a queue that supports VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_EXT on device");
								msgs[6] = true;
							}
							notSupported = true;
						}
					}
				}
			}

			i = notSupported ? usageFlags.erase(i) : std::next(i);
		}

		// remove duplicates
		for (auto i = usageFlags.begin(); i != usageFlags.end(); ++i)
		{
			for (auto j = std::next(i); j != usageFlags.end();)
				j = (*i == *j) ? usageFlags.erase(j) : std::next(j);
		}

		if (usageFlags.empty())
		{
			std::cout << str.str() << std::endl;
			TCU_THROW(NotSupportedError, "One or more buffer usage flags not supported by device");
		}
		else
		{
			if (entryCount > 0)
			{
				std::cout << str.str() << std::endl;
			}
			DE_ASSERT(m_instConfig.usageFlags.get());
			m_instConfig.usageFlags->resize(usageFlags.size());
			std::transform(usageFlags.begin(), usageFlags.end(), m_instConfig.usageFlags->begin(),
						   [](BufferUsageBits& bits){ return BufferUsageBits::makeShared(std::move(bits)); });
		}
	}

	// check the external memory handle type bits and build instance input
	{
		std::vector<ExternalMemoryHandleBits>	extMemHandleFlags;
		if (m_testConfig.incExtMemTypeFlags)
			extMemHandleFlags.push_back({AvailableExternalMemoryHandleBits.get(INTERNALTEST_EXTERNAL_MEMORY_HANDLE_TYPE_NO_BITS)});
		else
		{
			std::vector<VkExternalMemoryHandleTypeFlags>	handleHints;
			std::vector<ExternalMemoryHandleBits>			handleFlagsTmp;
			u::combine(handleFlagsTmp, AvailableExternalMemoryHandleBits.select<2>(true), handleHints);
			u::mergeFlags(extMemHandleFlags, handleFlagsTmp);
		}

		DE_ASSERT(m_instConfig.extMemHandleFlags.get());
		m_instConfig.extMemHandleFlags->resize(extMemHandleFlags.size());
		std::transform(extMemHandleFlags.begin(), extMemHandleFlags.end(), m_instConfig.extMemHandleFlags->begin(),
					   [](ExternalMemoryHandleBits& bits){ return ExternalMemoryHandleBits::makeShared(std::move(bits)); });
	}

	if (m_testConfig.testSizeRequirements)
	{
		if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance4"))
			TCU_THROW(NotSupportedError, "VK_KHR_maintenance4 not supported");
	}
}

void BufferMemoryRequirementsInstance::logFailedSubtests (const std::vector<BufferCreateBitsPtr>&			failCreateBits,
														  const std::vector<BufferUsageBitsPtr>&			failUsageBits,
														  const std::vector<ExternalMemoryHandleBitsPtr>&	failExtMemHandleBits) const
{
	const deUint32	flagCount	= deUint32(failCreateBits.size());
	TestLog&		log			= m_context.getTestContext().getLog();
	deUint32		entries		= 0;

	DE_ASSERT(flagCount && flagCount == failUsageBits.size() && flagCount == failExtMemHandleBits.size());

	log << TestLog::Section("Failed", "Failed subtests");

	for (deUint32 i = 0; i < flagCount; ++i)
	{
		{
			log << TestLog::Section("VkBufferCreateFlags", "Buffer create flags");
			auto msg = log << TestLog::Message;
			entries = 0;
			for (const auto& createBit : *failCreateBits[i])
			{
				if (entries++) msg << " ";
				const VkBufferCreateFlags flags = BufferCreateBits::extract(createBit);
				if (flags == 0)
					msg << "0";
				else msg << getBufferCreateFlagsStr(flags);
			}
			msg << TestLog::EndMessage << TestLog::EndSection;
		}

		{
			log << TestLog::Section("VkBufferUsageFlags", "Buffer usage flags");
			auto msg = log << TestLog::Message;
			entries = 0;
			for (const auto& usageBit : *failUsageBits[i])
			{
				if (entries++) msg << " ";
				msg << getBufferUsageFlagsStr(BufferUsageBits::extract(usageBit));
			}
			msg << TestLog::EndMessage << TestLog::EndSection;
		}

		{
			log << TestLog::Section("VkExternalMemoryHandleTypeFlags", "External memory handle type flags");
			auto msg = log << TestLog::Message;
			entries = 0;
			for (const auto& extMemHandleTypeBit : *failExtMemHandleBits[i])
			{
				if (entries++) msg << " ";
				msg << getExternalMemoryHandleTypeFlagsStr(ExternalMemoryHandleBits::extract(extMemHandleTypeBit));
			}
			msg << TestLog::EndMessage << TestLog::EndSection;
		}
	}

	log << TestLog::EndSection;
}

void BufferMemoryRequirementsInstance::getBufferMemoryRequirements2	(VkMemoryRequirements&	result,
																	 const DeviceInterface&	vkd,
																	 VkDevice				device,
																	 VkBuffer				buffer) const
{
	VkMemoryDedicatedRequirements	dedicatedRequirements	=
	{
		VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,		// VkStructureType			sType;
		nullptr,												// const void*				pNext;
		VK_FALSE,												// VkBool32					prefersDedicatedAllocation
		VK_FALSE												// VkBool32					requiresDedicatedAllocation
	};

	VkMemoryRequirements2			desiredRequirements		=
	{
		VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,				// VkStructureType			sType
		&dedicatedRequirements,									// void*					pNext
		result													// VkMemoryRequirements		memoryRequirements
	};

	VkBufferMemoryRequirementsInfo2	requirementsInfo		=
	{
		VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,	// VkStructureType			sType
		nullptr,												// const void*				pNext
		buffer													// VkBuffer					buffer
	};

	vkd.getBufferMemoryRequirements2(device, &requirementsInfo, &desiredRequirements);

	result = desiredRequirements.memoryRequirements;
}

void BufferMemoryRequirementsInstance::getBufferMemoryRequirements	(VkMemoryRequirements&	result,
																	 const DeviceInterface&	vkd,
																	 VkDevice				device,
																	 VkBuffer				buffer) const
{
	vkd.getBufferMemoryRequirements(device, buffer, &result);
}

template<> void*
BufferMemoryRequirementsInstance::chainVkStructure<VkExternalMemoryBufferCreateInfo> (void* pNext, const VkExternalMemoryHandleTypeFlags& handleTypes) const
{
	static VkExternalMemoryBufferCreateInfo	memInfo{};
	memInfo.sType		= VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO;
	memInfo.pNext		= pNext;
	memInfo.handleTypes	= handleTypes;

	return &memInfo;
}

template<> void* BufferMemoryRequirementsInstance::chainVkStructure<VkVideoProfilesKHR> (void* pNext, const VkBufferUsageFlags& videoCodecUsage) const
{
	const bool encode = (videoCodecUsage & VK_BUFFER_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) || (videoCodecUsage & VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR);
	const bool decode = (videoCodecUsage & VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR) || (videoCodecUsage & VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR);

	static VkVideoEncodeH264ProfileEXT	encodeProfile
	{
		VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_EXT,		// VkStructureType						sType;
		nullptr,												// const void*							pNext;
		STD_VIDEO_H264_PROFILE_IDC_BASELINE						// StdVideoH264ProfileIdc				stdProfileIdc;
	};

	static VkVideoDecodeH264ProfileEXT	decodeProfile
	{
		VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_EXT,		// VkStructureType						sType;
		nullptr,												// const void*							pNext;
		STD_VIDEO_H264_PROFILE_IDC_BASELINE,					// StdVideoH264ProfileIdc				stdProfileIdc;
		VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_EXT		// VkVideoDecodeH264FieldLayoutFlagsEXT	fieldLayout;
	};

	static const VkVideoProfileKHR	videoProfiles[]
	{
		// encode profile
		{
			VK_STRUCTURE_TYPE_VIDEO_PROFILE_KHR,				// VkStructureType						sType;
			&encodeProfile,										// void*								pNext;
			VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT,		// VkVideoCodecOperationFlagBitsKHR		videoCodecOperation;
			VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR,		// VkVideoChromaSubsamplingFlagsKHR		chromaSubsampling;
			VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR,				// VkVideoComponentBitDepthFlagsKHR		lumaBitDepth;
			VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR				// VkVideoComponentBitDepthFlagsKHR		chromaBitDepth;
		},
		// decode profile
		{
			VK_STRUCTURE_TYPE_VIDEO_PROFILE_KHR,				// VkStructureType						sType;
			&decodeProfile,										// void*								pNext;
			VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_EXT,		// VkVideoCodecOperationFlagBitsKHR		videoCodecOperation;
			VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR,		// VkVideoChromaSubsamplingFlagsKHR		chromaSubsampling;
			VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR,				// VkVideoComponentBitDepthFlagsKHR		lumaBitDepth;
			VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR				// VkVideoComponentBitDepthFlagsKHR		chromaBitDepth;
		}
	};
	static VkVideoProfilesKHR	profiles;
	profiles.sType			= VK_STRUCTURE_TYPE_VIDEO_PROFILES_KHR;
	profiles.pNext			= pNext;
	if (encode && decode)
	{
		profiles.profileCount	= 2u;
		profiles.pProfiles		= videoProfiles;
	}
	else if (encode)
	{
		profiles.profileCount	= 1u;
		profiles.pProfiles		= &videoProfiles[0];
	}
	else
	{
		profiles.profileCount	= 1u;
		profiles.pProfiles		= &videoProfiles[1];
	}
	return &profiles;
}

TestStatus	BufferMemoryRequirementsInstance::iterate (void)
{
	const DeviceInterface&							vkd					= m_context.getDeviceInterface();
	const VkDevice									device				= m_context.getDevice();
	const deUint32									queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	const Method									method				= m_config.useMethod2
																			? &BufferMemoryRequirementsInstance::getBufferMemoryRequirements2
																			: &BufferMemoryRequirementsInstance::getBufferMemoryRequirements;

	deUint32										passCount			= 0;
	deUint32										failCount			= 0;
	std::vector<BufferCreateBitsPtr>				failCreateBits;
	std::vector<BufferUsageBitsPtr>					failUsageBits;
	std::vector<ExternalMemoryHandleBitsPtr>		failExtMemHandleBits;

	DE_ASSERT(!m_config.createBits->empty());
	const VkBufferCreateFlags infoCreateFlags = *m_config.createBits;
	{
		DE_ASSERT(!m_config.usageFlags->empty());
		for (auto u = m_config.usageFlags->cbegin(); u != m_config.usageFlags->cend(); ++u)
		{
			const VkBufferUsageFlags infoUsageFlags = *(u->get());

			DE_ASSERT(!m_config.extMemHandleFlags->empty());
			for (auto m = m_config.extMemHandleFlags->cbegin(); m != m_config.extMemHandleFlags->cend(); ++m)
			{
				const VkExternalMemoryHandleTypeFlags handleFlags = *(m->get());

				void* pNext = nullptr;

				if (m_config.fateBits->contains(BufferFateFlagBits::Video))
				{
					pNext = chainVkStructure<VkVideoProfilesKHR>(pNext, infoUsageFlags);
				}
				if (m_config.incExtMemTypeFlags)
				{
					pNext = chainVkStructure<VkExternalMemoryBufferCreateInfo>(pNext, handleFlags);
				}
				VkBufferCreateInfo	createInfo
				{
					VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,					// VkStructureType					sType;
					pNext,													// const void*						pNext;
					infoCreateFlags,										// VkBufferCreateFlags				flags;
					4096u,													// VkDeviceSize						size;
					infoUsageFlags,											// VkBufferUsageFlags				usage;
					VK_SHARING_MODE_EXCLUSIVE,								// VkSharingMode					sharingMode;
					1u,														// uint32_t							queueFamilyIndexCount;
					&queueFamilyIndex,										// const uint32_t*					pQueueFamilyIndices;
				};

				if (m_config.testSizeRequirements)
				{
					VkPhysicalDeviceMaintenance4PropertiesKHR	maintenance4Properties		=
					{
						VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR,	// VkStructureType	sType;
						DE_NULL,														// void*			pNext;
						0u																// VkDeviceSize		maxBufferSize;
					};

					VkPhysicalDeviceProperties2					physicalDeviceProperties2	=
					{
						VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,	// VkStructureType				sType;
						&maintenance4Properties,						// void*						pNext;
						{},												// VkPhysicalDeviceProperties	properties;
					};

					m_context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &physicalDeviceProperties2);

					const VkDeviceSize							maxBufferSize				= maintenance4Properties.maxBufferSize;
					DE_ASSERT(maxBufferSize > 0);
					VkDeviceSize								N							= 0;

					while ((1ull << N) + 1 < maxBufferSize)
					{
						createInfo.size = (1ull << N) + 1;

						try
						{
							Move<VkBuffer> buffer = createBuffer(vkd, device, &createInfo);

							VkMemoryRequirements reqs{};
							(this->*method)(reqs, vkd, device, *buffer);

							if (reqs.size <= static_cast<VkDeviceSize>(deAlign64(static_cast<deInt64>(createInfo.size), static_cast<deInt64>(reqs.alignment))))
							{
								++passCount;
							} else
							{
								++failCount;
								failCreateBits.emplace_back(m_config.createBits);
								failUsageBits.emplace_back(*u);
								failExtMemHandleBits.emplace_back(*m);
							}

							N++;
						}
						catch (const vk::OutOfMemoryError&)
						{
							break;
						}
					}

					if (m_context.getTestContext().getWatchDog())
						qpWatchDog_reset(m_context.getTestContext().getWatchDog());
				}
				else
				{
					Move<VkBuffer> buffer = createBuffer(vkd, device, &createInfo);

					VkMemoryRequirements reqs{};
					(this->*method)(reqs, vkd, device, *buffer);
					if (reqs.memoryTypeBits)
						++passCount;
					else
					{
						++failCount;
						failCreateBits.emplace_back(m_config.createBits);
						failUsageBits.emplace_back(*u);
						failExtMemHandleBits.emplace_back(*m);
					}
				}
			}
		}
	}

	if (failCount)
	{
		logFailedSubtests(failCreateBits, failUsageBits, failExtMemHandleBits);
		return TestStatus::fail(std::to_string(failCount));
	}

	return TestStatus::pass(std::to_string(passCount));
}

} // unnamed namespace

tcu::TestCaseGroup* createBufferMemoryRequirementsTests (tcu::TestContext& testCtx)
{
	cstr nilstr = "";

	struct
	{
		bool		include;
		cstr		name;
	} const extMemTypeFlags[] { { false, "ext_mem_flags_excluded" }, { true, "ext_mem_flags_included" } };

	struct
	{
		bool		method;
		cstr		name;
	} const methods[] { { false, "method1" }, { true, "method2" } };

	std::vector<SharedPtr<BufferCreateBits>>	createBitPtrs;
	{
		std::vector<VkBufferCreateFlags>		hints;
		std::vector<BufferCreateBits>			createFlags;
		u::combine(createFlags,	AvailableBufferCreateBits, hints);
		updateBufferCreateFlags(createFlags);
		createBitPtrs.resize(createFlags.size());
		std::transform(createFlags.begin(), createFlags.end(), createBitPtrs.begin(),
					   [](BufferCreateBits& bits) { return BufferCreateBits::makeShared(std::move(bits)); });
	}

	std::vector<SharedPtr<BufferFateBits>>	fateBitPtrs;
	{
		// An excerpt above has been disabled consciously for the sake of computational complexity.
		// Enabled block does the same things sequentially, it doesn't create cartesian product of combination of bits.
#if 0
		std::vector<BufferFateFlags>	hints;
		std::vector<BufferFateBits>		bufferFateFlags;
		u::combine(bufferFateFlags, AvailableBufferFateBits, hints);
		fateBitPtrs.resize(bufferFateFlags.size());
		std::transform(bufferFateFlags.begin(), bufferFateFlags.end(), fateBitPtrs.begin(),
					   [](BufferFateBits& bits) { return BufferFateBits::makeShared(std::move(bits)); });
#else
		fateBitPtrs.resize(AvailableBufferFateBits.size());
		std::transform(AvailableBufferFateBits.begin(), AvailableBufferFateBits.end(), fateBitPtrs.begin(),
					   [](const typename BufferFateBits::value_type& bit) { return BufferFateBits::makeShared(bit); });
#endif
	}

	auto groupRoot = new TestCaseGroup(testCtx, "buffer_memory_requirements", "vkGetBufferMemoryRequirements*(...) routines tests.");
	for (const auto& createBits : createBitPtrs)
	{
		auto groupCreate = new TestCaseGroup(testCtx, bitsToString(*createBits, "create_").c_str(), nilstr);
		for (const auto& extMemTypeFlag : extMemTypeFlags)
		{
			auto groupExtMemTypeFlags = new TestCaseGroup(testCtx, extMemTypeFlag.name, nilstr);
			for (const auto& method : methods)
			{
				auto groupMethod = new TestCaseGroup(testCtx, method.name, nilstr);
				for (const auto& fateBits : fateBitPtrs)
				{
					for (const auto testSizeReq : {false, true})
					{
						TestConfig	config;
						config.fateBits				= fateBits;
						config.incExtMemTypeFlags	= extMemTypeFlag.include;
						config.createBits			= createBits;
						config.useMethod2			= method.method;
						config.testSizeRequirements	= testSizeReq;
						groupMethod->addChild(new MemoryRequirementsTest(testCtx, ((testSizeReq ? "size_req_" : "") + bitsToString(*fateBits)).c_str(), config));
					}
				}
				groupExtMemTypeFlags->addChild(groupMethod);
			}
			groupCreate->addChild(groupExtMemTypeFlags);
		}
		groupRoot->addChild(groupCreate);
	}

	return groupRoot;
}
} // api
} // vkt
