/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2020 The Khronos Group Inc.
 *
 * 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 Modifiers tests
 *//*--------------------------------------------------------------------*/

#include "vktModifiersTests.hpp"
#include "vktTestCase.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktTestCaseUtil.hpp"
#include "vktExternalMemoryUtil.hpp"
#include "vktImageTestsUtil.hpp"
#include "vkRefUtil.hpp"
#include "vkBufferWithMemory.hpp"
#include "vkBarrierUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkTypeUtil.hpp"
#include "tcuTestLog.hpp"
#include "tcuTexture.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuImageIO.hpp"
#include "tcuImageCompare.hpp"
#include "deUniquePtr.hpp"
#include "deStringUtil.hpp"

#include <string>

namespace vkt
{
namespace modifiers
{
namespace
{
using namespace vk;
using tcu::UVec2;
using tcu::TestLog;

void checkModifiersSupported (Context& context, VkFormat)
{
	if (!context.isDeviceFunctionalitySupported("VK_EXT_image_drm_format_modifier"))
		TCU_THROW(NotSupportedError, "VK_EXT_image_drm_format_modifier is not supported");

	if (!context.isInstanceFunctionalitySupported("VK_KHR_get_physical_device_properties2"))
		TCU_THROW(TestError, "VK_KHR_get_physical_device_properties2 not supported");

	if (!context.isDeviceFunctionalitySupported("VK_KHR_bind_memory2"))
		TCU_THROW(TestError, "VK_KHR_bind_memory2 not supported");

	if (!context.isDeviceFunctionalitySupported("VK_KHR_image_format_list"))
		TCU_THROW(TestError, "VK_KHR_image_format_list not supported");
}

std::string getFormatCaseName (VkFormat format)
{
	return de::toLower(de::toString(getFormatStr(format)).substr(10));
}

std::vector<VkDrmFormatModifierPropertiesEXT> getDrmFormatModifiers (const InstanceInterface&	vki,
																	 VkPhysicalDevice			physicalDevice,
																	 VkFormat					format)
{
	VkDrmFormatModifierPropertiesListEXT			modifierProperties;
	deMemset(&modifierProperties, 0, sizeof(modifierProperties));

	modifierProperties.sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT;
	VkFormatProperties2								formatProperties;
	deMemset(&formatProperties, 0, sizeof(formatProperties));

	std::vector<VkDrmFormatModifierPropertiesEXT>	drmFormatModifiers;
	formatProperties.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
	formatProperties.pNext = &modifierProperties;

	vki.getPhysicalDeviceFormatProperties2(physicalDevice, format, &formatProperties);

	drmFormatModifiers.resize(modifierProperties.drmFormatModifierCount);
	modifierProperties.pDrmFormatModifierProperties = drmFormatModifiers.data();

	vki.getPhysicalDeviceFormatProperties2(physicalDevice, format, &formatProperties);

	return drmFormatModifiers;
}

VkImageFormatProperties2 verifyHandleTypeForFormatModifier (const InstanceInterface&	vki,
															  VkPhysicalDevice			physicalDevice,
															  const VkFormat			format,
															  const VkImageType			imageType,
															  const VkImageUsageFlags	imageUsages,
															  const VkExternalMemoryHandleTypeFlags handleType,
															  const deUint64			drmFormatModifier)
{
	const VkPhysicalDeviceImageDrmFormatModifierInfoEXT	imageFormatModifierInfo	=
	{
		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
		DE_NULL,
		drmFormatModifier,
		VK_SHARING_MODE_EXCLUSIVE,
		0,
		DE_NULL,
	};
	const VkPhysicalDeviceExternalImageFormatInfo externalImageFormatInfo =
	{
		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
		&imageFormatModifierInfo,
		(VkExternalMemoryHandleTypeFlagBits)handleType,
	};
	const VkPhysicalDeviceImageFormatInfo2				imageFormatInfo			=
	{
		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
		&externalImageFormatInfo,
		format,
		imageType,
		VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
		imageUsages,
		0,
	};
	VkExternalImageFormatProperties	externalImageProperties;
	deMemset(&externalImageProperties, 0, sizeof(externalImageProperties));
	externalImageProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES;
	externalImageProperties.sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES;

	VkImageFormatProperties2							imageProperties;
	deMemset(&imageProperties, 0, sizeof(imageProperties));
	imageProperties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
	imageProperties.pNext = &externalImageProperties;
	if (vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &imageFormatInfo, &imageProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
	{
		TCU_THROW(NotSupportedError, de::toString(format) + " does not support any DRM modifiers");
	};
	if ((externalImageProperties.externalMemoryProperties.compatibleHandleTypes & handleType) != handleType)
	{
		TCU_THROW(NotSupportedError, de::toString(format) + " does not support the expected memory handle type");
	}

	return imageProperties;
}

void checkExportImportExtensions (Context& context, VkFormat format)
{
	// tcuTexture.cpp getChannelSize, that is used by intThresholdCompare does not support the following formats.
	// TODO: Add tcuTexture.cpp support for the following formats.
	const VkFormat					skippedFormats[]				=
	{
		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
		VK_FORMAT_A2R10G10B10_SNORM_PACK32,
		VK_FORMAT_A2R10G10B10_USCALED_PACK32,
		VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
		VK_FORMAT_A2R10G10B10_UINT_PACK32,
		VK_FORMAT_A2R10G10B10_SINT_PACK32,
		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
		VK_FORMAT_A2B10G10R10_SNORM_PACK32,
		VK_FORMAT_A2B10G10R10_USCALED_PACK32,
		VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
		VK_FORMAT_A2B10G10R10_UINT_PACK32,
		VK_FORMAT_A2B10G10R10_SINT_PACK32,
	};

	if (std::find(std::begin(skippedFormats), std::end(skippedFormats), format) != std::end(skippedFormats))
		TCU_THROW(NotSupportedError, de::toString(format) + " can't be checked for correctness");

	if (!context.isDeviceFunctionalitySupported("VK_KHR_external_memory_fd"))
		TCU_THROW(NotSupportedError, "VK_KHR_external_memory_fd not supported");
	checkModifiersSupported(context, format);

	const InstanceInterface&						vki					= context.getInstanceInterface();
	std::vector<VkDrmFormatModifierPropertiesEXT>	drmFormatModifiers	= getDrmFormatModifiers(vki, context.getPhysicalDevice(), format);

	if (drmFormatModifiers.size() < 1)
		TCU_THROW(NotSupportedError, de::toString(format) + " does not support any DRM modifiers");
	bool												featureCompatible				= false;
	for (deUint32 m = 0; m < drmFormatModifiers.size(); m++)
	{
		const VkFormatFeatureFlags							testFeatures		= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
		if ((drmFormatModifiers[m].drmFormatModifierTilingFeatures & testFeatures) != testFeatures)
			continue;
		verifyHandleTypeForFormatModifier(vki, context.getPhysicalDevice(), format,
																			VK_IMAGE_TYPE_2D,
																			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
																			VK_IMAGE_USAGE_SAMPLED_BIT,
																			VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
																			drmFormatModifiers[m].drmFormatModifier);

		featureCompatible = true;
	}
	if (!featureCompatible)
		TCU_THROW(NotSupportedError, "Could not find a format modifier supporting required transfer features for " + de::toString(format));
}

deBool isModifierCompatibleWithImageProperties (const InstanceInterface&	vki,
												VkPhysicalDevice			physicalDevice,
												const VkFormat*				formats,
												const deUint32				nFormats,
												const VkImageType			imageType,
												const VkImageUsageFlags		imageUsages,
												const deUint64				drmFormatModifier,
												VkImageFormatProperties2&	imageProperties)
{
	const VkPhysicalDeviceImageDrmFormatModifierInfoEXT	imageFormatModifierInfo	=
	{
		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
		DE_NULL,
		drmFormatModifier,
		VK_SHARING_MODE_EXCLUSIVE,
		0,
		DE_NULL,
	};
	const VkImageFormatListCreateInfoKHR				imageFormatListInfo		=
	{
		VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR,
		&imageFormatModifierInfo,
		nFormats,
		formats,
	};
	const VkPhysicalDeviceImageFormatInfo2				imageFormatInfo			=
	{
		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
		&imageFormatListInfo,
		formats[0],
		imageType,
		VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
		imageUsages,
		0,
	};

	imageProperties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;

	return vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &imageFormatInfo, &imageProperties) != VK_ERROR_FORMAT_NOT_SUPPORTED;
}

tcu::TestStatus listModifiersCase (Context& context, VkFormat format)
{
	TestLog&										log					= context.getTestContext().getLog();
	const InstanceInterface&						vki					= context.getInstanceInterface();
	std::vector<VkDrmFormatModifierPropertiesEXT>	drmFormatModifiers	= getDrmFormatModifiers(vki, context.getPhysicalDevice(), format);

	if (drmFormatModifiers.size() < 1)
		TCU_THROW(NotSupportedError, de::toString(format) + " does not support any DRM modifiers");

	for (deUint32 m = 0; m < drmFormatModifiers.size(); m++) {
		VkImageFormatProperties2	imageProperties {};
		deBool	isCompatible	= isModifierCompatibleWithImageProperties(vki, context.getPhysicalDevice(),
																		  &format, 1u, VK_IMAGE_TYPE_2D,
																		  VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
																		  drmFormatModifiers[m].drmFormatModifier, imageProperties);

		if (!isCompatible)
			TCU_THROW(NotSupportedError, de::toString(format) + " does not support any DRM modifiers");

		TCU_CHECK(imageProperties.imageFormatProperties.maxExtent.width >= 1 && imageProperties.imageFormatProperties.maxExtent.height >= 1);
		TCU_CHECK(imageProperties.imageFormatProperties.maxArrayLayers >= 1);

		log << TestLog::Message
			<< "format modifier " << m << ":\n"
			<< drmFormatModifiers[m] << "\n"
			<< imageProperties
			<< TestLog::EndMessage;
	}

	return tcu::TestStatus::pass("OK");
}

Move<VkImage> createImageNoModifiers (const DeviceInterface&			vkd,
												 const VkDevice					device,
												 const VkImageUsageFlags		imageUsages,
												 const VkFormat					format,
												 const UVec2&					size)
{
	const VkImageCreateInfo							createInfo	=
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
		DE_NULL,
		0,
		VK_IMAGE_TYPE_2D,
		format,
		makeExtent3D(size.x(), size.y(), 1u),
		1u,		// mipLevels
		1u,		// arrayLayers
		VK_SAMPLE_COUNT_1_BIT,
		VK_IMAGE_TILING_OPTIMAL,
		imageUsages,
		VK_SHARING_MODE_EXCLUSIVE,
		0u,
		(const deUint32*)DE_NULL,
		VK_IMAGE_LAYOUT_PREINITIALIZED,
	};

	return createImage(vkd, device, &createInfo);
}

Move<VkImage> createImageWithDrmFormatModifiers (const DeviceInterface&			vkd,
												 const VkDevice					device,
												 const VkImageType				imageType,
												 const VkImageUsageFlags		imageUsages,
												 const VkExternalMemoryHandleTypeFlags		externalMemoryHandleTypeFlags,
												 const std::vector<VkFormat>					formats,
												 const UVec2&					size,
												 const std::vector<deUint64>&	drmFormatModifiers)
{
	const VkImageDrmFormatModifierListCreateInfoEXT	modifierListCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT,
		DE_NULL,
		(deUint32)drmFormatModifiers.size(),
		drmFormatModifiers.data(),
	};

	const VkExternalMemoryImageCreateInfo externalMemoryCreateInfo =
	{
		VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
		&modifierListCreateInfo,
		externalMemoryHandleTypeFlags,
	};

	const void* pNext = &externalMemoryCreateInfo;
	if (!externalMemoryHandleTypeFlags)
	{
		pNext = &modifierListCreateInfo;
	}

	const VkImageFormatListCreateInfoKHR			imageFormatListInfo			=
	{
		VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR,
		pNext,
		static_cast<deUint32>(formats.size()),
		formats.data(),
	};

	const VkImageCreateInfo							createInfo	=
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
		&imageFormatListInfo,
		0,
		imageType,
		formats.front(),
		makeExtent3D(size.x(), size.y(), 1u),
		1u,		// mipLevels
		1u,		// arrayLayers
		VK_SAMPLE_COUNT_1_BIT,
		VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
		imageUsages,
		VK_SHARING_MODE_EXCLUSIVE,
		0u,
		(const deUint32*)DE_NULL,
		VK_IMAGE_LAYOUT_UNDEFINED,
	};

	return createImage(vkd, device, &createInfo);
}

tcu::TestStatus createImageListModifiersCase (Context& context, const VkFormat format)
{
	const InstanceInterface&						vki					= context.getInstanceInterface();
	const DeviceInterface&							vkd					= context.getDeviceInterface();
	const VkDevice									device				= context.getDevice();
	std::vector<VkDrmFormatModifierPropertiesEXT>	drmFormatModifiers	= getDrmFormatModifiers(vki, context.getPhysicalDevice(), format);

	if (drmFormatModifiers.size() < 1)
		TCU_THROW(NotSupportedError, de::toString(format) + " does not support any DRM modifiers");

	for (deUint32 modifierNdx = 0; modifierNdx < drmFormatModifiers.size(); modifierNdx++) {
		VkImageDrmFormatModifierPropertiesEXT	properties;
		std::vector<deUint64>					modifiers;
		bool									found		= false;

		deMemset(&properties, 0, sizeof(properties));
		properties.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT;

		for (deUint32 m = 0; m <= modifierNdx; m++)
		{
			VkImageFormatProperties2 imgFormatProperties {};
			deBool isCompatible	= isModifierCompatibleWithImageProperties(vki, context.getPhysicalDevice(), &format, 1u, VK_IMAGE_TYPE_2D,
																		  VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
																		  drmFormatModifiers[m].drmFormatModifier, imgFormatProperties);
			if (isCompatible)
				modifiers.push_back(drmFormatModifiers[m].drmFormatModifier);
		}

		if (modifiers.empty())
			TCU_THROW(NotSupportedError, de::toString(format) + " does not support any DRM modifiers");

		{
			Move<VkImage>						image		(createImageWithDrmFormatModifiers(vkd, device, VK_IMAGE_TYPE_2D,
																								 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
																								 VK_IMAGE_USAGE_SAMPLED_BIT,
																								 0,
																								 {format}, UVec2(64, 64), modifiers));


			VK_CHECK(vkd.getImageDrmFormatModifierPropertiesEXT(device, *image, &properties));
		}

		for (deUint32 m = 0; m < modifiers.size(); m++)
		{
			if (properties.drmFormatModifier == modifiers[m]) {
				found = true;
				break;
			}
		}

		if (!found)
			return tcu::TestStatus::fail("Image created with modifier not specified in the create list");
	}

	return tcu::TestStatus::pass("OK");
}

deUint32 chooseMemoryType(deUint32 bits)
{
	DE_ASSERT(bits != 0);

	for (deUint32 memoryTypeIndex = 0; (1u << memoryTypeIndex) <= bits; memoryTypeIndex++)
	{
		if ((bits & (1u << memoryTypeIndex)) != 0)
			return memoryTypeIndex;
	}

	DE_FATAL("No supported memory types");
	return -1;
}

bool exportImportMemoryExplicitModifiersCase (Context& context, const VkFormat format, const VkDrmFormatModifierPropertiesEXT& modifier)
{
	const InstanceInterface&						vki					= context.getInstanceInterface();
	const DeviceInterface&							vkd					= context.getDeviceInterface();
	const VkDevice									device				= context.getDevice();


	verifyHandleTypeForFormatModifier(vki, context.getPhysicalDevice(), format,
																		VK_IMAGE_TYPE_2D,
																		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
																		VK_IMAGE_USAGE_SAMPLED_BIT,
																		VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
																		modifier.drmFormatModifier);
	std::vector<deUint64>					modifiers;
	modifiers.push_back(modifier.drmFormatModifier);


	const UVec2									imageSize		(64, 64);
	const tcu::TextureFormat referenceTextureFormat (mapVkFormat(format));
	deUint32 bufferSize = 1<<16;
	const de::UniquePtr<BufferWithMemory>		inputBuffer		(new BufferWithMemory(vkd, device, context.getDefaultAllocator(),
																																							makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT),
																						MemoryRequirement::HostVisible));
	tcu::PixelBufferAccess				referenceImage	(referenceTextureFormat, imageSize.x(), imageSize.y(), 1, inputBuffer->getAllocation().getHostPtr());
	const de::UniquePtr<BufferWithMemory>		outputBuffer		(new BufferWithMemory(vkd, device, context.getDefaultAllocator(),
																																							makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT),
																						MemoryRequirement::HostVisible));
	Unique<VkCommandPool>			cmdPool				(createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex(), DE_NULL));
	vkt::ExternalMemoryUtil::NativeHandle								inputImageMemFd;

	const tcu::TextureFormatInfo				formatInfo		(tcu::getTextureFormatInfo(referenceTextureFormat));
	tcu::fillWithComponentGradients(referenceImage, formatInfo.valueMin, formatInfo.valueMax);

	flushAlloc(vkd, device, inputBuffer->getAllocation());

	Move<VkImage>						srcImage		(createImageNoModifiers(vkd, device,
																								 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
																								 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
																								 format, UVec2(64, 64)));
	VkMemoryRequirements srcImageMemoryReq = getImageMemoryRequirements(vkd, device, *srcImage);
	const vk::VkMemoryAllocateInfo	allocationInfo	=
	{
		vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
		DE_NULL,
		srcImageMemoryReq.size,
		chooseMemoryType(srcImageMemoryReq.memoryTypeBits),
	};
	vk::Move<vk::VkDeviceMemory>	srcMemory			(vk::allocateMemory(vkd, device, &allocationInfo));
	VK_CHECK(vkd.bindImageMemory(device, *srcImage, *srcMemory, 0));


	Unique<VkCommandBuffer>			cmdBuffer			(allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
	const VkCommandBufferBeginInfo	cmdBufferBeginInfo	=
	{
		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
		DE_NULL,
		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
		(const VkCommandBufferInheritanceInfo*)DE_NULL,
	};

	VK_CHECK(vkd.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));

	{
		const VkImageAspectFlags		aspect				= VK_IMAGE_ASPECT_COLOR_BIT;
		std::vector<VkBufferImageCopy>	copies;

		copies.push_back(image::makeBufferImageCopy(makeExtent3D(imageSize.x(), imageSize.y(), 1u), 1u));
		copyBufferToImage(vkd, *cmdBuffer, inputBuffer->get(), bufferSize,
											copies, aspect, 1, 1, *srcImage,
											VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);

	}

	Move<VkImage>						dstImage		(createImageWithDrmFormatModifiers(vkd, device, VK_IMAGE_TYPE_2D,
																																				 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
																																				 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
																																				 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
																																				 {format}, UVec2(64, 64), modifiers));
	VkMemoryRequirements dstImageMemoryReq = getImageMemoryRequirements(vkd, device, *dstImage);
	vk::Move<vk::VkDeviceMemory>	dstMemory			(vkt::ExternalMemoryUtil::allocateExportableMemory(vkd, device,
																																																 dstImageMemoryReq.size,
																																																 chooseMemoryType(dstImageMemoryReq.memoryTypeBits),
																																																 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
																																																 *dstImage));

	VK_CHECK(vkd.bindImageMemory(device, *dstImage, *dstMemory, 0));
	const VkImageMemoryBarrier		srcImageBarrier		=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout;
		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,			// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
		*srcImage,						// VkImage					image;
		{											// VkImageSubresourceRange	subresourceRange;
			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
			0u,								// deUint32				baseMipLevel;
			1u,								// deUint32				mipLevels;
			0u,								// deUint32				baseArraySlice;
			1u								// deUint32				arraySize;
		}
	};
	const VkImageMemoryBarrier		dstImageBarrier		=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
		VK_IMAGE_LAYOUT_UNDEFINED,		// VkImageLayout			oldLayout;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
		*dstImage,						// VkImage					image;
		{											// VkImageSubresourceRange	subresourceRange;
			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
			0u,								// deUint32				baseMipLevel;
			1u,								// deUint32				mipLevels;
			0u,								// deUint32				baseArraySlice;
			1u								// deUint32				arraySize;
		}
	};
	vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &srcImageBarrier);
	vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &dstImageBarrier);

	VkImageBlit		imageBlit
	{
		{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
		{{0,0,0}, {64,64,1}},
		{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
		{{0,0,0}, {64,64,1}},
	};
	vkd.cmdBlitImage(*cmdBuffer, *srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dstImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageBlit, VK_FILTER_NEAREST);

	VK_CHECK(vkd.endCommandBuffer(*cmdBuffer));
	submitCommandsAndWait(vkd, device, context.getUniversalQueue(), *cmdBuffer);
	VkImageDrmFormatModifierPropertiesEXT	properties;
	deMemset(&properties, 0, sizeof(properties));
	properties.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT;
	VK_CHECK(vkd.getImageDrmFormatModifierPropertiesEXT(device, *dstImage, &properties));
	TCU_CHECK(properties.drmFormatModifier == modifiers.front());
	inputImageMemFd	= vkt::ExternalMemoryUtil::getMemoryFd(vkd, device, *dstMemory, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT);

	Move<VkImage>				importedSrcImage		(createImageWithDrmFormatModifiers(vkd, device, VK_IMAGE_TYPE_2D,
																																						 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
																																						 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
																																						 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
																																						 {format}, UVec2(64, 64), modifiers));

	VkMemoryRequirements importedSrcImageMemoryReq = getImageMemoryRequirements(vkd, device, *importedSrcImage);

	Move<VkDeviceMemory>						importedMemory (vkt::ExternalMemoryUtil::importDedicatedMemory(vkd, device, *importedSrcImage,
                                                                                                               importedSrcImageMemoryReq,
                                                                                                               VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
                                                                                                               ~0u, inputImageMemFd));
	VK_CHECK(vkd.bindImageMemory(device, *importedSrcImage, *importedMemory, 0));

	Move<VkImage>						outImage		(createImageNoModifiers(vkd, device,
																															VK_IMAGE_USAGE_TRANSFER_DST_BIT |
																															VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
																															format, UVec2(64, 64)));
	VkMemoryRequirements outImageMemoryReq = getImageMemoryRequirements(vkd, device, *outImage);
	const vk::VkMemoryAllocateInfo	outAllocationInfo	=
	{
		vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
		DE_NULL,
		outImageMemoryReq.size,
		chooseMemoryType(outImageMemoryReq.memoryTypeBits),
	};
	vk::Move<vk::VkDeviceMemory>	outMemory			(vk::allocateMemory(vkd, device, &outAllocationInfo));
	VK_CHECK(vkd.bindImageMemory(device, *outImage, *outMemory, 0));

	Unique<VkCommandBuffer>			cmdBuffer2			(allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
	VK_CHECK(vkd.beginCommandBuffer(*cmdBuffer2, &cmdBufferBeginInfo));

	const VkImageMemoryBarrier		importedImageBarrier		=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout;
		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,			// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_FOREIGN_EXT,					// deUint32					srcQueueFamilyIndex;
		context.getUniversalQueueFamilyIndex(),			// deUint32					dstQueueFamilyIndex;
		*importedSrcImage,						// VkImage					image;
		{											// VkImageSubresourceRange	subresourceRange;
			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
			0u,								// deUint32				baseMipLevel;
			1u,								// deUint32				mipLevels;
			0u,								// deUint32				baseArraySlice;
			1u								// deUint32				arraySize;
		}
	};
	const VkImageMemoryBarrier		outImageBarrier		=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
		VK_IMAGE_LAYOUT_UNDEFINED,		// VkImageLayout			oldLayout;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
		*outImage,						// VkImage					image;
		{											// VkImageSubresourceRange	subresourceRange;
			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
			0u,								// deUint32				baseMipLevel;
			1u,								// deUint32				mipLevels;
			0u,								// deUint32				baseArraySlice;
			1u								// deUint32				arraySize;
		}
	};

	vkd.cmdPipelineBarrier(*cmdBuffer2, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &importedImageBarrier);
	vkd.cmdPipelineBarrier(*cmdBuffer2, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &outImageBarrier);

	VkImageBlit		imageBlit2
	{
		{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
		{{0,0,0}, {64,64,1}},
		{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
		{{0,0,0}, {64,64,1}},
	};
	vkd.cmdBlitImage(*cmdBuffer2, *importedSrcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *outImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageBlit2, VK_FILTER_NEAREST);


	copyImageToBuffer(vkd, *cmdBuffer2, *outImage,
										outputBuffer->get(), tcu::IVec2(imageSize.x(), imageSize.y()),
										VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1);

	VK_CHECK(vkd.endCommandBuffer(*cmdBuffer2));

	submitCommandsAndWait(vkd, device, context.getUniversalQueue(), *cmdBuffer2);


	tcu::ConstPixelBufferAccess	result	(referenceTextureFormat, imageSize.x(), imageSize.y(), 1, outputBuffer->getAllocation().getHostPtr());
	const tcu::UVec4 threshold (0u);

	return tcu::intThresholdCompare(context.getTestContext().getLog(), "Compare", "Result comparison", referenceImage, result, threshold, tcu::COMPARE_LOG_RESULT);
}

tcu::TestStatus exportImportMemoryExplicitModifiersCase (Context& context, const VkFormat format)
{
	const InstanceInterface&						vki					= context.getInstanceInterface();
	std::vector<VkDrmFormatModifierPropertiesEXT>	drmFormatModifiers	= getDrmFormatModifiers(vki, context.getPhysicalDevice(), format);

	for (deUint32 m = 0; m < drmFormatModifiers.size(); m++)
	{
		const VkFormatFeatureFlags							testFeatures		= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
		if ((drmFormatModifiers[m].drmFormatModifierTilingFeatures & testFeatures) != testFeatures)
			continue;
		if (!exportImportMemoryExplicitModifiersCase(context, format, drmFormatModifiers[m]))
			return tcu::TestStatus::fail("Unexpected copy image result");
	}

	return tcu::TestStatus::pass("OK");
}

} // anonymous

tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup>	drmFormatModifiersGroup	(new tcu::TestCaseGroup(testCtx, "drm_format_modifiers", "DRM format modifiers tests"));
	const VkFormat					formats[]				=
	{
		VK_FORMAT_R4G4_UNORM_PACK8,
		VK_FORMAT_R4G4B4A4_UNORM_PACK16,
		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
		VK_FORMAT_R5G6B5_UNORM_PACK16,
		VK_FORMAT_B5G6R5_UNORM_PACK16,
		VK_FORMAT_R5G5B5A1_UNORM_PACK16,
		VK_FORMAT_B5G5R5A1_UNORM_PACK16,
		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
		VK_FORMAT_R8_UNORM,
		VK_FORMAT_R8_SNORM,
		VK_FORMAT_R8_USCALED,
		VK_FORMAT_R8_SSCALED,
		VK_FORMAT_R8_UINT,
		VK_FORMAT_R8_SINT,
		VK_FORMAT_R8_SRGB,
		VK_FORMAT_R8G8_UNORM,
		VK_FORMAT_R8G8_SNORM,
		VK_FORMAT_R8G8_USCALED,
		VK_FORMAT_R8G8_SSCALED,
		VK_FORMAT_R8G8_UINT,
		VK_FORMAT_R8G8_SINT,
		VK_FORMAT_R8G8_SRGB,
		VK_FORMAT_R8G8B8_UNORM,
		VK_FORMAT_R8G8B8_SNORM,
		VK_FORMAT_R8G8B8_USCALED,
		VK_FORMAT_R8G8B8_SSCALED,
		VK_FORMAT_R8G8B8_UINT,
		VK_FORMAT_R8G8B8_SINT,
		VK_FORMAT_R8G8B8_SRGB,
		VK_FORMAT_B8G8R8_UNORM,
		VK_FORMAT_B8G8R8_SNORM,
		VK_FORMAT_B8G8R8_USCALED,
		VK_FORMAT_B8G8R8_SSCALED,
		VK_FORMAT_B8G8R8_UINT,
		VK_FORMAT_B8G8R8_SINT,
		VK_FORMAT_B8G8R8_SRGB,
		VK_FORMAT_R8G8B8A8_UNORM,
		VK_FORMAT_R8G8B8A8_SNORM,
		VK_FORMAT_R8G8B8A8_USCALED,
		VK_FORMAT_R8G8B8A8_SSCALED,
		VK_FORMAT_R8G8B8A8_UINT,
		VK_FORMAT_R8G8B8A8_SINT,
		VK_FORMAT_R8G8B8A8_SRGB,
		VK_FORMAT_B8G8R8A8_UNORM,
		VK_FORMAT_B8G8R8A8_SNORM,
		VK_FORMAT_B8G8R8A8_USCALED,
		VK_FORMAT_B8G8R8A8_SSCALED,
		VK_FORMAT_B8G8R8A8_UINT,
		VK_FORMAT_B8G8R8A8_SINT,
		VK_FORMAT_B8G8R8A8_SRGB,
		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
		VK_FORMAT_A8B8G8R8_USCALED_PACK32,
		VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
		VK_FORMAT_A8B8G8R8_UINT_PACK32,
		VK_FORMAT_A8B8G8R8_SINT_PACK32,
		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
		VK_FORMAT_A2R10G10B10_SNORM_PACK32,
		VK_FORMAT_A2R10G10B10_USCALED_PACK32,
		VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
		VK_FORMAT_A2R10G10B10_UINT_PACK32,
		VK_FORMAT_A2R10G10B10_SINT_PACK32,
		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
		VK_FORMAT_A2B10G10R10_SNORM_PACK32,
		VK_FORMAT_A2B10G10R10_USCALED_PACK32,
		VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
		VK_FORMAT_A2B10G10R10_UINT_PACK32,
		VK_FORMAT_A2B10G10R10_SINT_PACK32,
		VK_FORMAT_R16_UNORM,
		VK_FORMAT_R16_SNORM,
		VK_FORMAT_R16_USCALED,
		VK_FORMAT_R16_SSCALED,
		VK_FORMAT_R16_UINT,
		VK_FORMAT_R16_SINT,
		VK_FORMAT_R16_SFLOAT,
		VK_FORMAT_R16G16_UNORM,
		VK_FORMAT_R16G16_SNORM,
		VK_FORMAT_R16G16_USCALED,
		VK_FORMAT_R16G16_SSCALED,
		VK_FORMAT_R16G16_UINT,
		VK_FORMAT_R16G16_SINT,
		VK_FORMAT_R16G16_SFLOAT,
		VK_FORMAT_R16G16B16_UNORM,
		VK_FORMAT_R16G16B16_SNORM,
		VK_FORMAT_R16G16B16_USCALED,
		VK_FORMAT_R16G16B16_SSCALED,
		VK_FORMAT_R16G16B16_UINT,
		VK_FORMAT_R16G16B16_SINT,
		VK_FORMAT_R16G16B16_SFLOAT,
		VK_FORMAT_R16G16B16A16_UNORM,
		VK_FORMAT_R16G16B16A16_SNORM,
		VK_FORMAT_R16G16B16A16_USCALED,
		VK_FORMAT_R16G16B16A16_SSCALED,
		VK_FORMAT_R16G16B16A16_UINT,
		VK_FORMAT_R16G16B16A16_SINT,
		VK_FORMAT_R16G16B16A16_SFLOAT,
		VK_FORMAT_R32_UINT,
		VK_FORMAT_R32_SINT,
		VK_FORMAT_R32_SFLOAT,
		VK_FORMAT_R32G32_UINT,
		VK_FORMAT_R32G32_SINT,
		VK_FORMAT_R32G32_SFLOAT,
		VK_FORMAT_R32G32B32_UINT,
		VK_FORMAT_R32G32B32_SINT,
		VK_FORMAT_R32G32B32_SFLOAT,
		VK_FORMAT_R32G32B32A32_UINT,
		VK_FORMAT_R32G32B32A32_SINT,
		VK_FORMAT_R32G32B32A32_SFLOAT,
		VK_FORMAT_R64_UINT,
		VK_FORMAT_R64_SINT,
		VK_FORMAT_R64_SFLOAT,
		VK_FORMAT_R64G64_UINT,
		VK_FORMAT_R64G64_SINT,
		VK_FORMAT_R64G64_SFLOAT,
		VK_FORMAT_R64G64B64_UINT,
		VK_FORMAT_R64G64B64_SINT,
		VK_FORMAT_R64G64B64_SFLOAT,
		VK_FORMAT_R64G64B64A64_UINT,
		VK_FORMAT_R64G64B64A64_SINT,
		VK_FORMAT_R64G64B64A64_SFLOAT,
		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
	};

	{
		de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "list_modifiers", "Check that listing supported modifiers is functional"));

		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
			addFunctionCase(group.get(), getFormatCaseName(formats[formatNdx]), "Check that listing supported modifiers is functional", checkModifiersSupported, listModifiersCase, formats[formatNdx]);

		drmFormatModifiersGroup->addChild(group.release());
	}

	{
		de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "create_list_modifiers", "Check that creating images with modifier list is functional"));

		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
			addFunctionCase(group.get(), getFormatCaseName(formats[formatNdx]), "Check that creating images with modifier list is functional", checkModifiersSupported, createImageListModifiersCase, formats[formatNdx]);

		drmFormatModifiersGroup->addChild(group.release());
	}

	{
		de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "export_import", "Test exporting/importing images with modifiers"));

		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
			addFunctionCase(group.get(), getFormatCaseName(formats[formatNdx]), "Test exporting/importing images with modifiers", checkExportImportExtensions, exportImportMemoryExplicitModifiersCase, formats[formatNdx]);

		drmFormatModifiersGroup->addChild(group.release());
	}

	return drmFormatModifiersGroup.release();
}

} // modifiers
} // vkt
