/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2017 The Khronos Group Inc.
 * Copyright (c) 2017 Google 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  vktSparseResourcesImageBlockShapes.cpp
 * \brief Standard block shape tests.
 *//*--------------------------------------------------------------------*/

#include "vktSparseResourcesBufferSparseBinding.hpp"
#include "vktSparseResourcesTestsUtil.hpp"
#include "vktSparseResourcesBase.hpp"
#include "vktTestCaseUtil.hpp"

#include "vkDefs.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vkPlatform.hpp"
#include "vkPrograms.hpp"
#include "vkMemUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkTypeUtil.hpp"

#include "deUniquePtr.hpp"
#include "deStringUtil.hpp"

#include <string>
#include <vector>

using namespace vk;

namespace vkt
{
namespace sparse
{
namespace
{

class ImageBlockShapesCase : public TestCase
{
public:
	ImageBlockShapesCase			(tcu::TestContext&	testCtx,
									 const std::string&	name,
									 const std::string&	description,
									 const ImageType	imageType,
									 const tcu::UVec3&	imageSize,
									 const VkFormat		format,
									 deUint32			numSamples);

	void			initPrograms			(SourceCollections&			sourceCollections) const {DE_UNREF(sourceCollections);};
	TestInstance*	createInstance			(Context&					context) const;
	virtual void	checkSupport			(Context&					context) const;

private:
	const ImageType		m_imageType;
	const tcu::UVec3	m_imageSize;
	const VkFormat		m_format;
	const deUint32		m_numSamples;
};

ImageBlockShapesCase::ImageBlockShapesCase (tcu::TestContext&	testCtx,
											const std::string&	name,
											const std::string&	description,
											const ImageType		imageType,
											const tcu::UVec3&	imageSize,
											const VkFormat		format,
											deUint32			numSamples)
	: TestCase		(testCtx, name, description)
	, m_imageType	(imageType)
	, m_imageSize	(imageSize)
	, m_format		(format)
	, m_numSamples	(numSamples)
{
}

void ImageBlockShapesCase::checkSupport (Context& context) const
{
	const InstanceInterface&	instance		= context.getInstanceInterface();
	const VkPhysicalDevice		physicalDevice	= context.getPhysicalDevice();

	// Check the image size does not exceed device limits
	if (!isImageSizeSupported(instance, physicalDevice, m_imageType, m_imageSize))
		TCU_THROW(NotSupportedError, "Image size not supported for device");

	// Check if device supports sparse operations for image type
	if (!checkSparseSupportForImageType(instance, physicalDevice, m_imageType))
		TCU_THROW(NotSupportedError, "Sparse residency for image type is not supported");

	if (formatIsR64(m_format))
	{
		context.requireDeviceFunctionality("VK_EXT_shader_image_atomic_int64");

		if (context.getShaderImageAtomicInt64FeaturesEXT().sparseImageInt64Atomics == VK_FALSE)
		{
			TCU_THROW(NotSupportedError, "sparseImageInt64Atomics is not supported for device");
		}
	}
}

class ImageBlockShapesInstance : public SparseResourcesBaseInstance
{
public:
	ImageBlockShapesInstance	(Context&			context,
								 const ImageType	imageType,
								 const tcu::UVec3&	imageSize,
								 const VkFormat		format,
								 deUint32			numSamples);

	tcu::TestStatus	iterate		(void);

private:
	const ImageType		m_imageType;
	const tcu::UVec3	m_imageSize;
	const VkFormat		m_format;
	const deUint32		m_numSamples;
};

ImageBlockShapesInstance::ImageBlockShapesInstance (Context&			context,
													const ImageType		imageType,
													const tcu::UVec3&	imageSize,
													const VkFormat		format,
													deUint32			numSamples)
	: SparseResourcesBaseInstance	(context)
	, m_imageType					(imageType)
	, m_imageSize					(imageSize)
	, m_format						(format)
	, m_numSamples					(numSamples)
{
}

tcu::TestStatus ImageBlockShapesInstance::iterate (void)
{
	const InstanceInterface&						instance					= m_context.getInstanceInterface();
	const VkPhysicalDevice							physicalDevice				= m_context.getPhysicalDevice();
	const VkPhysicalDeviceProperties				physicalDeviceProperties	= getPhysicalDeviceProperties(instance, physicalDevice);
	VkImageCreateInfo								imageCreateInfo;
	std::vector<VkSparseImageMemoryRequirements>	sparseMemoryRequirements;
	const VkPhysicalDeviceSparseProperties			sparseProperties			= physicalDeviceProperties.sparseProperties;
	const PlanarFormatDescription					formatDescription			= getPlanarFormatDescription(m_format);

	imageCreateInfo.sType					= VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
	imageCreateInfo.pNext					= DE_NULL;
	imageCreateInfo.flags					= VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
	imageCreateInfo.imageType				= mapImageType(m_imageType);
	imageCreateInfo.format					= m_format;
	imageCreateInfo.extent					= makeExtent3D(getLayerSize(m_imageType, m_imageSize));
	imageCreateInfo.mipLevels				= 1u;
	imageCreateInfo.arrayLayers				= getNumLayers(m_imageType, m_imageSize);
	imageCreateInfo.samples					= static_cast<VkSampleCountFlagBits>(m_numSamples);
	imageCreateInfo.tiling					= VK_IMAGE_TILING_OPTIMAL;
	imageCreateInfo.initialLayout			= VK_IMAGE_LAYOUT_UNDEFINED;
	imageCreateInfo.usage					= VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
											  VK_IMAGE_USAGE_STORAGE_BIT;
	imageCreateInfo.sharingMode				= VK_SHARING_MODE_EXCLUSIVE;
	imageCreateInfo.queueFamilyIndexCount	= 0u;
	imageCreateInfo.pQueueFamilyIndices		= DE_NULL;

	if (m_imageType == IMAGE_TYPE_CUBE || m_imageType == IMAGE_TYPE_CUBE_ARRAY)
	{
		imageCreateInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
	}

	// Check the format supports given number of samples
	VkImageFormatProperties	imageFormatProperties;

	if (instance.getPhysicalDeviceImageFormatProperties(physicalDevice,
		imageCreateInfo.format,
		imageCreateInfo.imageType,
		imageCreateInfo.tiling,
		imageCreateInfo.usage,
		imageCreateInfo.flags,
		&imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
	{
		TCU_THROW(NotSupportedError, "Image format does not support sparse operations");
	}

	if (!(imageFormatProperties.sampleCounts & imageCreateInfo.samples))
		TCU_THROW(NotSupportedError, "The image format does not support the number of samples specified");

	// Check if device supports sparse operations for image format
	if (!checkSparseSupportForImageFormat(instance, physicalDevice, imageCreateInfo))
		TCU_THROW(NotSupportedError, "The image format does not support sparse operations");

	{
		QueueRequirementsVec queueRequirements;
		queueRequirements.push_back(QueueRequirements(VK_QUEUE_SPARSE_BINDING_BIT, 1u));

		createDeviceSupportingQueues(queueRequirements);
	}

	{
		const DeviceInterface&		deviceInterface	= getDeviceInterface();

		// Create sparse image
		const Unique<VkImage>		imageSparse( createImage(deviceInterface, getDevice(), &imageCreateInfo) );

		// Get sparse image sparse memory requirements
		sparseMemoryRequirements	= getImageSparseMemoryRequirements(deviceInterface, getDevice(), *imageSparse);

		DE_ASSERT(sparseMemoryRequirements.size() != 0);
	}

	for (deUint32 planeNdx = 0; planeNdx < formatDescription.numPlanes; ++planeNdx)
	{
		const VkImageAspectFlags		aspect				= (formatDescription.numPlanes > 1) ? getPlaneAspect(planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT;
		const deUint32					aspectIndex			= getSparseAspectRequirementsIndex(sparseMemoryRequirements, aspect);

		if (aspectIndex == NO_MATCH_FOUND)
			TCU_THROW(NotSupportedError, "Not supported image aspect");

		VkSparseImageMemoryRequirements	aspectRequirements	= sparseMemoryRequirements[aspectIndex];
		VkExtent3D						imageGranularity	= aspectRequirements.formatProperties.imageGranularity;
		deUint32						pixelSize			= static_cast<deUint32>(formatDescription.planes[planeNdx].elementSizeBytes) * 8u;
		VkExtent3D						expectedGranularity;

		if (m_imageType == IMAGE_TYPE_3D)
		{
			if (!sparseProperties.residencyStandard3DBlockShape)
				return tcu::TestStatus::pass("Pass (residencyStandard3DBlockShape disabled)");

			switch (pixelSize)
			{
				case 8:
					expectedGranularity.width = 64;
					expectedGranularity.height = 32;
					expectedGranularity.depth = 32;
					break;
				case 16:
					expectedGranularity.width = 32;
					expectedGranularity.height = 32;
					expectedGranularity.depth = 32;
					break;
				case 32:
					expectedGranularity.width = 32;
					expectedGranularity.height = 32;
					expectedGranularity.depth = 16;
					break;
				case 64:
					expectedGranularity.width = 32;
					expectedGranularity.height = 16;
					expectedGranularity.depth = 16;
					break;
				default:
					DE_ASSERT(pixelSize == 128);
					expectedGranularity.width = 16;
					expectedGranularity.height = 16;
					expectedGranularity.depth = 16;
					break;
			};
		}
		else if (m_numSamples == 2)
		{
			if (!sparseProperties.residencyStandard2DMultisampleBlockShape)
				return tcu::TestStatus::pass("Pass (residencyStandard2DMultisampleBlockShape disabled)");

			expectedGranularity.depth = 1;

			switch (pixelSize)
			{
				case 8:
					expectedGranularity.width = 128;
					expectedGranularity.height = 256;
					break;
				case 16:
					expectedGranularity.width = 128;
					expectedGranularity.height = 128;
					break;
				case 32:
					expectedGranularity.width = 64;
					expectedGranularity.height = 128;
					break;
				case 64:
					expectedGranularity.width = 64;
					expectedGranularity.height = 64;
					break;
				default:
					DE_ASSERT(pixelSize == 128);
					expectedGranularity.width = 32;
					expectedGranularity.height = 64;
					break;
			};
		}
		else if (m_numSamples == 4)
		{
			if (!sparseProperties.residencyStandard2DMultisampleBlockShape)
				return tcu::TestStatus::pass("Pass (residencyStandard2DMultisampleBlockShape disabled)");

			expectedGranularity.depth = 1;

			switch (pixelSize)
			{
				case 8:
					expectedGranularity.width = 128;
					expectedGranularity.height = 128;
					break;
				case 16:
					expectedGranularity.width = 128;
					expectedGranularity.height = 64;
					break;
				case 32:
					expectedGranularity.width = 64;
					expectedGranularity.height = 64;
					break;
				case 64:
					expectedGranularity.width = 64;
					expectedGranularity.height = 32;
					break;
				default:
					DE_ASSERT(pixelSize == 128);
					expectedGranularity.width = 32;
					expectedGranularity.height = 32;
					break;
			};
		}
		else if (m_numSamples == 8)
		{
			if (!sparseProperties.residencyStandard2DMultisampleBlockShape)
				return tcu::TestStatus::pass("Pass (residencyStandard2DMultisampleBlockShape disabled)");

			expectedGranularity.depth = 1;

			switch (pixelSize)
			{
				case 8:
					expectedGranularity.width = 64;
					expectedGranularity.height = 128;
					break;
				case 16:
					expectedGranularity.width = 64;
					expectedGranularity.height = 64;
					break;
				case 32:
					expectedGranularity.width = 32;
					expectedGranularity.height = 64;
					break;
				case 64:
					expectedGranularity.width = 32;
					expectedGranularity.height = 32;
					break;
				default:
					DE_ASSERT(pixelSize == 128);
					expectedGranularity.width = 16;
					expectedGranularity.height = 32;
					break;
			};
		}
		else if (m_numSamples == 16)
		{
			if (!sparseProperties.residencyStandard2DMultisampleBlockShape)
				return tcu::TestStatus::pass("Pass (residencyStandard2DMultisampleBlockShape disabled)");

			expectedGranularity.depth = 1;

			switch (pixelSize)
			{
				case 8:
					expectedGranularity.width = 64;
					expectedGranularity.height = 64;
					break;
				case 16:
					expectedGranularity.width = 64;
					expectedGranularity.height = 32;
					break;
				case 32:
					expectedGranularity.width = 32;
					expectedGranularity.height = 32;
					break;
				case 64:
					expectedGranularity.width = 32;
					expectedGranularity.height = 16;
					break;
				default:
					DE_ASSERT(pixelSize == 128);
					expectedGranularity.width = 16;
					expectedGranularity.height = 16;
					break;
			};
		}
		else
		{
			DE_ASSERT(m_numSamples == 1);

			if (!sparseProperties.residencyStandard2DBlockShape)
				return tcu::TestStatus::pass("Pass (residencyStandard2DBlockShape disabled)");

			expectedGranularity.depth = 1;

			switch (pixelSize)
			{
				case 8:
					expectedGranularity.width = 256;
					expectedGranularity.height = 256;
					break;
				case 16:
					expectedGranularity.width = 256;
					expectedGranularity.height = 128;
					break;
				case 32:
					expectedGranularity.width = 128;
					expectedGranularity.height = 128;
					break;
				case 64:
					expectedGranularity.width = 128;
					expectedGranularity.height = 64;
					break;
				default:
					DE_ASSERT(pixelSize == 128);
					expectedGranularity.width = 64;
					expectedGranularity.height = 64;
					break;
			};
		}

		if (   imageGranularity.width  != expectedGranularity.width
			|| imageGranularity.height != expectedGranularity.height
			|| imageGranularity.depth  != expectedGranularity.depth)
		{
			return tcu::TestStatus::fail("Non-standard block shape used");
		}
	}
	return tcu::TestStatus::pass("Passed");
}

TestInstance* ImageBlockShapesCase::createInstance (Context& context) const
{
	return new ImageBlockShapesInstance(context, m_imageType, m_imageSize, m_format, m_numSamples);
}

} // anonymous ns

tcu::TestCaseGroup* createImageBlockShapesTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "image_block_shapes", "Standard block shape"));

	const std::vector<TestImageParameters> imageParameters =
	{
		{ IMAGE_TYPE_2D,			{ tcu::UVec3(512u, 256u, 1u) },		getTestFormats(IMAGE_TYPE_2D) },
		{ IMAGE_TYPE_2D_ARRAY,		{ tcu::UVec3(512u, 256u, 6u) },		getTestFormats(IMAGE_TYPE_2D_ARRAY) },
		{ IMAGE_TYPE_CUBE,			{ tcu::UVec3(256u, 256u, 1u) },		getTestFormats(IMAGE_TYPE_CUBE) },
		{ IMAGE_TYPE_CUBE_ARRAY,	{ tcu::UVec3(256u, 256u, 6u) },		getTestFormats(IMAGE_TYPE_CUBE_ARRAY) },
		{ IMAGE_TYPE_3D,			{ tcu::UVec3(512u, 256u, 16u) },	getTestFormats(IMAGE_TYPE_3D) }
	};

	static const deUint32 sampleCounts[] = { 1u, 2u, 4u, 8u, 16u };

	for (size_t imageTypeNdx = 0; imageTypeNdx < imageParameters.size(); ++imageTypeNdx)
	{
		const ImageType					imageType = imageParameters[imageTypeNdx].imageType;
		de::MovePtr<tcu::TestCaseGroup> imageTypeGroup(new tcu::TestCaseGroup(testCtx, getImageTypeName(imageType).c_str(), ""));

		for (size_t formatNdx = 0; formatNdx < imageParameters[imageTypeNdx].formats.size(); ++formatNdx)
		{
			VkFormat						format				= imageParameters[imageTypeNdx].formats[formatNdx].format;
			tcu::UVec3						imageSizeAlignment	= getImageSizeAlignment(format);
			de::MovePtr<tcu::TestCaseGroup> formatGroup			(new tcu::TestCaseGroup(testCtx, getImageFormatID(format).c_str(), ""));

			for (deInt32 sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); ++sampleCountNdx)
			{
				for (size_t imageSizeNdx = 0; imageSizeNdx < imageParameters[imageTypeNdx].imageSizes.size(); ++imageSizeNdx)
				{
					const tcu::UVec3	imageSize = imageParameters[imageTypeNdx].imageSizes[imageSizeNdx];

					// skip test for images with odd sizes for some YCbCr formats
					if ((imageSize.x() % imageSizeAlignment.x()) != 0)
						continue;
					if ((imageSize.y() % imageSizeAlignment.y()) != 0)
						continue;

					const deUint32		sampleCount = sampleCounts[sampleCountNdx];
					const std::string	name = std::string("samples_") + de::toString(sampleCount);

					formatGroup->addChild(new ImageBlockShapesCase(testCtx, name.c_str(), "", imageType, imageSize, format, sampleCount));
				}
			}
			imageTypeGroup->addChild(formatGroup.release());
		}
		testGroup->addChild(imageTypeGroup.release());
	}

	return testGroup.release();
}

} // sparse
} // vkt
