/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2015 Google Inc.
 * Copyright (c) 2019-2020 NVIDIA Corporation
 *
 * 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 Fragment Shading Rate tests
 *//*--------------------------------------------------------------------*/

#include "vktFragmentShadingRateTests.hpp"
#include "vktFragmentShadingRateBasic.hpp"
#include "vktFragmentShadingRatePixelConsistency.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktTestCaseUtil.hpp"
#include "tcuTestLog.hpp"
#include <limits>

namespace vkt
{
namespace FragmentShadingRate
{

namespace
{

tcu::TestStatus testLimits(Context& context)
{
	bool			allChecksPassed					= true;
	tcu::TestLog&	log								= context.getTestContext().getLog();
	const auto&		features						= context.getDeviceFeatures();
	const auto&		properties						= context.getDeviceProperties();
	const auto&		vulkan12Features				= context.getDeviceVulkan12Features();
	const auto&		fragmentShadingRateFeatures		= context.getFragmentShadingRateFeatures();
	const auto&		fragmentShadingRateProperties	= context.getFragmentShadingRateProperties();

	if (!fragmentShadingRateFeatures.pipelineFragmentShadingRate)
	{
		log << tcu::TestLog::Message << "pipelineFragmentShadingRate is not supported" << tcu::TestLog::EndMessage;
		allChecksPassed = false;
	}

	if (context.getFragmentShadingRateProperties().primitiveFragmentShadingRateWithMultipleViewports && !context.getFragmentShadingRateFeatures().primitiveFragmentShadingRate)
	{
		log << tcu::TestLog::Message << "primitiveFragmentShadingRateWithMultipleViewports "
										"limit should only be supported if primitiveFragmentShadingRate is supported" << tcu::TestLog::EndMessage;
		allChecksPassed = false;
	}

	bool requiredFeatures = features.geometryShader || vulkan12Features.shaderOutputViewportIndex || context.isDeviceFunctionalitySupported("VK_EXT_shader_viewport_index_layer");
	if (context.getFragmentShadingRateProperties().primitiveFragmentShadingRateWithMultipleViewports && !requiredFeatures)
	{
		log << tcu::TestLog::Message << "primitiveFragmentShadingRateWithMultipleViewports limit should only "
										"be supported if at least one of the geometryShader feature, shaderOutputViewportIndex feature, "
										"or VK_EXT_shader_viewport_index_layer extension is supported" << tcu::TestLog::EndMessage;
		allChecksPassed = false;
	}

	if (fragmentShadingRateProperties.layeredShadingRateAttachments && !fragmentShadingRateFeatures.attachmentFragmentShadingRate)
	{
		log << tcu::TestLog::Message << "layeredShadingRateAttachments should only be supported if attachmentFragmentShadingRate is supported" << tcu::TestLog::EndMessage;
		allChecksPassed = false;
	}

	requiredFeatures = features.geometryShader || context.getMultiviewFeatures().multiview || vulkan12Features.shaderOutputViewportIndex ||
						context.isDeviceFunctionalitySupported("VK_EXT_shader_viewport_index_layer");
	if (fragmentShadingRateProperties.layeredShadingRateAttachments && !requiredFeatures)
	{
		log << tcu::TestLog::Message << "layeredShadingRateAttachments should only be supported if at least one of the geometryShader feature, multiview feature, "
										"shaderOutputViewportIndex feature, or VK_EXT_shader_viewport_index_layer extension is supported" << tcu::TestLog::EndMessage;
		allChecksPassed = false;
	}

	requiredFeatures = fragmentShadingRateFeatures.primitiveFragmentShadingRate || fragmentShadingRateFeatures.attachmentFragmentShadingRate;
	if (fragmentShadingRateProperties.fragmentShadingRateNonTrivialCombinerOps && !requiredFeatures)
	{
		log << tcu::TestLog::Message << "fragmentShadingRateNonTrivialCombinerOps should only be supported if at least one of primitiveFragmentShadingRate "
										"or attachmentFragmentShadingRate is supported" << tcu::TestLog::EndMessage;
		allChecksPassed = false;
	}

	if (fragmentShadingRateProperties.maxFragmentSizeAspectRatio > std::max(fragmentShadingRateProperties.maxFragmentSize.width, fragmentShadingRateProperties.maxFragmentSize.height))
	{
		log << tcu::TestLog::Message << "maxFragmentSizeAspectRatio should be less than or equal to the maximum width / height of maxFragmentSize" << tcu::TestLog::EndMessage;
		allChecksPassed = false;
	}

	if (fragmentShadingRateProperties.maxFragmentSizeAspectRatio < 2)
	{
		log << tcu::TestLog::Message << "maxFragmentSizeAspectRatio should be at least 2" << tcu::TestLog::EndMessage;
		allChecksPassed = false;
	}

	if (!deIntIsPow2(static_cast<int>(fragmentShadingRateProperties.maxFragmentSizeAspectRatio)))
	{
		log << tcu::TestLog::Message << "maxFragmentSizeAspectRatio should be power of 2" << tcu::TestLog::EndMessage;
		allChecksPassed = false;
	}

	if (fragmentShadingRateProperties.fragmentShadingRateWithShaderSampleMask && (fragmentShadingRateProperties.maxFragmentShadingRateCoverageSamples > (properties.limits.maxSampleMaskWords * 32)))
	{
		log << tcu::TestLog::Message << "maxFragmentShadingRateCoverageSamples should be less than or equal maxSampleMaskWords * 32 "
										"if fragmentShadingRateWithShaderSampleMask is supported" << tcu::TestLog::EndMessage;
		allChecksPassed = false;
	}

	deUint32 requiredValue = fragmentShadingRateProperties.maxFragmentSize.width * fragmentShadingRateProperties.maxFragmentSize.height *
								fragmentShadingRateProperties.maxFragmentShadingRateRasterizationSamples;
	if (fragmentShadingRateProperties.maxFragmentShadingRateCoverageSamples > requiredValue)
	{
		log << tcu::TestLog::Message << "maxFragmentShadingRateCoverageSamples should be less than or equal to the product of the width and height of "
										"maxFragmentSize and the samples reported by maxFragmentShadingRateRasterizationSamples" << tcu::TestLog::EndMessage;
		allChecksPassed = false;
	}

	if (fragmentShadingRateProperties.maxFragmentShadingRateCoverageSamples < 16)
	{
		log << tcu::TestLog::Message << "maxFragmentShadingRateCoverageSamples should at least be 16" << tcu::TestLog::EndMessage;
		allChecksPassed = false;
	}

	if (fragmentShadingRateProperties.maxFragmentShadingRateRasterizationSamples < vk::VK_SAMPLE_COUNT_4_BIT)
	{
		log << tcu::TestLog::Message << "maxFragmentShadingRateRasterizationSamples should supports at least VK_SAMPLE_COUNT_4_BIT" << tcu::TestLog::EndMessage;
		allChecksPassed = false;
	}

	if (fragmentShadingRateProperties.fragmentShadingRateWithConservativeRasterization && !context.isDeviceFunctionalitySupported("VK_EXT_conservative_rasterization"))
	{
		log << tcu::TestLog::Message << "fragmentShadingRateWithConservativeRasterization should only be supported if VK_EXT_conservative_rasterization is supported" << tcu::TestLog::EndMessage;
		allChecksPassed = false;
	}

	if (fragmentShadingRateProperties.fragmentShadingRateWithFragmentShaderInterlock && !context.isDeviceFunctionalitySupported("VK_EXT_fragment_shader_interlock"))
	{
		log << tcu::TestLog::Message << "fragmentShadingRateWithFragmentShaderInterlock should only be supported if VK_EXT_fragment_shader_interlock is supported" << tcu::TestLog::EndMessage;
		allChecksPassed = false;
	}

	if (fragmentShadingRateProperties.fragmentShadingRateWithCustomSampleLocations && !context.isDeviceFunctionalitySupported("VK_EXT_sample_locations"))
	{
		log << tcu::TestLog::Message << "fragmentShadingRateWithCustomSampleLocations should only be supported if VK_EXT_sample_locations is supported" << tcu::TestLog::EndMessage;
		allChecksPassed = false;
	}

	if (fragmentShadingRateFeatures.attachmentFragmentShadingRate)
	{
		if ((fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.width < 8) ||
			(fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.height < 8))
		{
			log << tcu::TestLog::Message << "maxFragmentShadingRateAttachmentTexelSize should at least be { 8,8 }" << tcu::TestLog::EndMessage;
			allChecksPassed = false;
		}

		if ((fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.width > 32) ||
			(fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.height > 32))
		{
			log << tcu::TestLog::Message << "minFragmentShadingRateAttachmentTexelSize should't be greater than { 32,32 }" << tcu::TestLog::EndMessage;
			allChecksPassed = false;
		}

		if ((fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.width < fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.width) ||
			(fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.height < fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.height))
		{
			log << tcu::TestLog::Message << "maxFragmentShadingRateAttachmentTexelSize should be greater than or equal to "
				"minFragmentShadingRateAttachmentTexelSize in each dimension" << tcu::TestLog::EndMessage;
			allChecksPassed = false;
		}

		if (!deIntIsPow2(static_cast<int>(fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.width)) ||
			!deIntIsPow2(static_cast<int>(fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.height)))
		{
			log << tcu::TestLog::Message << "maxFragmentShadingRateAttachmentTexelSize should be power of 2" << tcu::TestLog::EndMessage;
			allChecksPassed = false;
		}

		if (!deIntIsPow2(static_cast<int>(fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.width)) ||
			!deIntIsPow2(static_cast<int>(fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.height)))
		{
			log << tcu::TestLog::Message << "minFragmentShadingRateAttachmentTexelSize should be power of 2" << tcu::TestLog::EndMessage;
			allChecksPassed = false;
		}
	}
	else
	{
		if ((fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.width != 0) ||
			(fragmentShadingRateProperties.maxFragmentShadingRateAttachmentTexelSize.height != 0))
		{
			log << tcu::TestLog::Message << "maxFragmentShadingRateAttachmentTexelSize should be { 0,0 } when "
											"attachmentFragmentShadingRate is not supported" << tcu::TestLog::EndMessage;
			allChecksPassed = false;
		}

		if ((fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.width != 0) ||
			(fragmentShadingRateProperties.minFragmentShadingRateAttachmentTexelSize.height != 0))
		{
			log << tcu::TestLog::Message << "minFragmentShadingRateAttachmentTexelSize should be { 0,0 } when "
											"attachmentFragmentShadingRate is not supported" << tcu::TestLog::EndMessage;
			allChecksPassed = false;
		}
	}

	if ((fragmentShadingRateProperties.maxFragmentSize.width < 2) ||
		(fragmentShadingRateProperties.maxFragmentSize.height < 2))
	{
		log << tcu::TestLog::Message << "maxFragmentSize should at least be { 2,2 }" << tcu::TestLog::EndMessage;
		allChecksPassed = false;
	}

	if ((fragmentShadingRateProperties.maxFragmentSize.width > 4) ||
		(fragmentShadingRateProperties.maxFragmentSize.height > 4))
	{
		log << tcu::TestLog::Message << "maxFragmentSize should't be greater than{ 4,4 }" << tcu::TestLog::EndMessage;
		allChecksPassed = false;
	}

	if (allChecksPassed)
		return tcu::TestStatus::pass("pass");
	return tcu::TestStatus::fail("fail");
}

tcu::TestStatus testShadingRates(Context& context)
{
	bool							someChecksFailed					= false;
	tcu::TestLog&					log									= context.getTestContext().getLog();
	const vk::InstanceInterface&	vki									= context.getInstanceInterface();
	vk::VkPhysicalDevice			physicalDevice						= context.getPhysicalDevice();
	const auto&						fragmentShadingRateProperties		= context.getFragmentShadingRateProperties();
	deUint32						supportedFragmentShadingRateCount	= 0;

	vk::VkResult result = vki.getPhysicalDeviceFragmentShadingRatesKHR(physicalDevice, &supportedFragmentShadingRateCount, DE_NULL);
	if ((result != vk::VK_SUCCESS) && (result != vk::VK_ERROR_OUT_OF_HOST_MEMORY))
	{
		someChecksFailed = true;
		log << tcu::TestLog::Message << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned invalid result" << tcu::TestLog::EndMessage;
	}

	std::vector<vk::VkPhysicalDeviceFragmentShadingRateKHR> fragmentShadingRateVect(supportedFragmentShadingRateCount);
	for (auto& fragmentShadingRate : fragmentShadingRateVect)
	{
		fragmentShadingRate.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR;
		fragmentShadingRate.pNext = DE_NULL;
	}

	// Pass a value of 1 into pFragmentShadingRateCount, and an array of at least length one into pFragmentShadingRates.
	// Check that the returned value is either VK_INCOMPLETE or VK_ERROR_OUT_OF_HOST_MEMORY(and issue a quality warning in the latter case).
	supportedFragmentShadingRateCount = 1u;
	result = vki.getPhysicalDeviceFragmentShadingRatesKHR(physicalDevice, &supportedFragmentShadingRateCount, fragmentShadingRateVect.data());
	if ((result != vk::VK_INCOMPLETE) && (result != vk::VK_ERROR_OUT_OF_HOST_MEMORY))
	{
		someChecksFailed = true;
		log << tcu::TestLog::Message << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned invalid result" << tcu::TestLog::EndMessage;
	}

	// Get all available fragment shading rates
	supportedFragmentShadingRateCount = static_cast<deUint32>(fragmentShadingRateVect.size());
	result = vki.getPhysicalDeviceFragmentShadingRatesKHR(physicalDevice, &supportedFragmentShadingRateCount, fragmentShadingRateVect.data());
	if ((result != vk::VK_SUCCESS) && (result != vk::VK_ERROR_OUT_OF_HOST_MEMORY))
	{
		someChecksFailed = true;
		log << tcu::TestLog::Message << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned invalid result" << tcu::TestLog::EndMessage;
	}

	bool		widthCheckPassed	= true;
	bool		heightCheckPassed	= true;
	deUint32	previousWidth		= std::numeric_limits<deUint32>::max();
	deUint32	previousHeight		= std::numeric_limits<deUint32>::max();

	for (const auto& fsr : fragmentShadingRateVect)
	{
		const auto& fragmentSize = fsr.fragmentSize;

		// Check that rate width and height are power-of-two
		if (!deIntIsPow2(static_cast<int>(fragmentSize.width)) ||
			!deIntIsPow2(static_cast<int>(fragmentSize.height)))
		{
			log << tcu::TestLog::Message << "fragmentSize should be power of 2" << tcu::TestLog::EndMessage;
			someChecksFailed = true;
		}

		// Check that the width and height are less than the values in the maxFragmentSize limit
		if ((fragmentSize.width > fragmentShadingRateProperties.maxFragmentSize.width) ||
			(fragmentSize.height > fragmentShadingRateProperties.maxFragmentSize.height))
		{
			log << tcu::TestLog::Message << "fragmentSize width and height are not less than the values in the maxFragmentSize" << tcu::TestLog::EndMessage;
			someChecksFailed = true;
		}

		if ((fragmentSize.width * fragmentSize.height) == 1)
		{
			// special case for fragmentSize {1, 1}
			if (fsr.sampleCounts != ~0u)
			{
				log << tcu::TestLog::Message << "implementations must support sampleCounts equal to ~0 for fragmentSize {1, 1}" << tcu::TestLog::EndMessage;
				someChecksFailed = true;
			}
		}
		else
		{
			// get highest sample count value
			deUint32 highestSampleCount = 0x80000000;
			while (highestSampleCount)
			{
				if (fsr.sampleCounts & highestSampleCount)
					break;
				highestSampleCount >>= 1;
			}

			// Check that the highest sample count in sampleCounts is less than or equal to maxFragmentShadingRateRasterizationSamples limit
			if (highestSampleCount > static_cast<deUint32>(fragmentShadingRateProperties.maxFragmentShadingRateRasterizationSamples))
			{
				log << tcu::TestLog::Message << "highest sample count value is not less than or equal to the maxFragmentShadingRateRasterizationSamples limit" << tcu::TestLog::EndMessage;
				someChecksFailed = true;
			}

			// Check that the product of the width, height, and highest sample count value is less than the maxFragmentShadingRateCoverageSamples limit
			if ((fragmentSize.width * fragmentSize.height * highestSampleCount) > fragmentShadingRateProperties.maxFragmentShadingRateCoverageSamples)
			{
				log << tcu::TestLog::Message << "product of the width, height, and highest sample count value is not less than the maxFragmentShadingRateCoverageSamples limit" << tcu::TestLog::EndMessage;
				someChecksFailed = true;
			}
		}

		// Check that the entries in the array are ordered first by largest to smallest width, then largest to smallest height
		{
			const deUint32 currentWidth = fragmentSize.width;
			if (widthCheckPassed && (currentWidth > previousWidth))
			{
				log << tcu::TestLog::Message << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned entries that are not ordered by largest to smallest width" << tcu::TestLog::EndMessage;
				widthCheckPassed = false;
			}

			deUint32 currentHeight = fragmentSize.height;
			if (heightCheckPassed)
			{
				// we can check order of height only for entries that have same width
				if (currentWidth == previousWidth)
				{
					if (currentHeight > previousHeight)
					{
						log << tcu::TestLog::Message << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned entries with same width but height is not ordered by largest to smallest" << tcu::TestLog::EndMessage;
						heightCheckPassed = false;
					}
				}
				else
					currentHeight = std::numeric_limits<deUint32>::max();
			}

			previousWidth = currentWidth;
			previousHeight = currentHeight;
		}

		// Check that no two entries in the array have the same fragmentSize.width and fragmentSize.height value
		{
			deUint32 count = 0;
			for (const auto& fsrB : fragmentShadingRateVect)
			{
				if ((fragmentSize.width  == fsrB.fragmentSize.width) &&
					(fragmentSize.height == fsrB.fragmentSize.height))
				{
					if (++count > 1)
					{
						log << tcu::TestLog::Message << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned entries with same fragmentSize" << tcu::TestLog::EndMessage;
						someChecksFailed = true;
						break;
					}
				}
			}
		}

		// Check that 1x1, 1x2, 2x1, and 2x2 rates are supported with sample counts of 1 and 4
		if ((fragmentSize.width < 3) && (fragmentSize.height < 3) &&
			(!(fsr.sampleCounts & vk::VK_SAMPLE_COUNT_1_BIT) || !(fsr.sampleCounts & vk::VK_SAMPLE_COUNT_4_BIT)))
		{
			log << tcu::TestLog::Message << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned 1x1, 1x2, 2x1, and 2x2 rates with sample counts not supporting 1 and 4" << tcu::TestLog::EndMessage;
			someChecksFailed = true;
		}

		// If the framebufferColorSampleCounts limit includes a sample count of 2, ensure that a sample count of 2 is also reported for the 1x1, 1x2, 2x1, and 2x2 rates.
		if (context.getDeviceProperties().limits.framebufferColorSampleCounts & vk::VK_SAMPLE_COUNT_2_BIT)
		{
			if ((fragmentSize.width < 3) && (fragmentSize.height < 3) &&
				!(fsr.sampleCounts & vk::VK_SAMPLE_COUNT_2_BIT))
			{
				log << tcu::TestLog::Message << "vkGetPhysicalDeviceFragmentShadingRatesKHR returned 1x1, 1x2, 2x1, and 2x2 rates with sample counts not supporting 2 while framebufferColorSampleCounts does" << tcu::TestLog::EndMessage;
				someChecksFailed = true;
			}
		}
	}

	if (someChecksFailed || !widthCheckPassed || !heightCheckPassed)
		return tcu::TestStatus::fail("fail");

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

void checkSupport(Context& context)
{
	context.requireDeviceFunctionality("VK_KHR_fragment_shading_rate");
}

void createMiscTests(tcu::TestContext& testCtx, tcu::TestCaseGroup* parentGroup)
{
	de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "misc", ""));

	addFunctionCase(group.get(), "limits",			"", checkSupport, testLimits);
	addFunctionCase(group.get(), "shading_rates",	"", checkSupport, testShadingRates);

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

void createChildren (tcu::TestContext& testCtx, tcu::TestCaseGroup* group, bool useDynamicRendering)
{
	createBasicTests(testCtx, group, useDynamicRendering);

	if (!useDynamicRendering)
	{
		// there is no point in duplicating those tests for dynamic rendering
		createMiscTests(testCtx, group);

		// subpasses can't be translated to dynamic rendering
		createPixelConsistencyTests(testCtx, group);
	}
}

} // anonymous

tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> mainGroup				(new tcu::TestCaseGroup(testCtx, "fragment_shading_rate", "Fragment shading rate tests"));
	de::MovePtr<tcu::TestCaseGroup> renderpass2Group		(new tcu::TestCaseGroup(testCtx, "renderpass2", "Draw using render pass object"));
	de::MovePtr<tcu::TestCaseGroup> dynamicRenderingGroup	(new tcu::TestCaseGroup(testCtx, "dynamic_rendering", "Draw using VK_KHR_dynamic_rendering"));

	createChildren(testCtx, renderpass2Group.get(), false);
	createChildren(testCtx, dynamicRenderingGroup.get(), true);

	mainGroup->addChild(renderpass2Group.release());
	mainGroup->addChild(dynamicRenderingGroup.release());

	return mainGroup.release();
}

} // FragmentShadingRate
} // vkt
