/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2016 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 Texture filtering anisotropy tests
 *//*--------------------------------------------------------------------*/

#include "vktTextureFilteringAnisotropyTests.hpp"

#include "vktTextureTestUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkQueryUtil.hpp"
#include "tcuImageCompare.hpp"
#include <vector>

using namespace vk;

namespace vkt
{
namespace texture
{

using std::string;
using std::vector;
using std::max;
using std::min;
using tcu::Vec2;
using tcu::Vec4;
using tcu::Sampler;
using tcu::Surface;
using tcu::TextureFormat;
using namespace texture::util;
using namespace glu::TextureTestUtil;

namespace
{
static const deUint32 ANISOTROPY_TEST_RESOLUTION = 128u;

struct AnisotropyParams : public ReferenceParams
{
	AnisotropyParams	(const TextureType			texType_,
						 const float				maxAnisotropy_,
						 const Sampler::FilterMode	minFilter_,
						 const Sampler::FilterMode	magFilter_,
						 const bool					mipMap_ = false)
		: ReferenceParams	(texType_)
		, maxAnisotropy		(maxAnisotropy_)
		, minFilter			(minFilter_)
		, magFilter			(magFilter_)
		, mipMap			(mipMap_)
	{
	}

	float				maxAnisotropy;
	Sampler::FilterMode	minFilter;
	Sampler::FilterMode	magFilter;
	bool				mipMap;
};

class FilteringAnisotropyInstance : public vkt::TestInstance
{
public:
	FilteringAnisotropyInstance	(Context& context, const AnisotropyParams& refParams)
		: vkt::TestInstance	(context)
		, m_refParams		(refParams)
	{
		// Sampling parameters.
		m_refParams.sampler			= util::createSampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, m_refParams.minFilter, m_refParams.magFilter);
		m_refParams.samplerType		= getSamplerType(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM));
		m_refParams.flags			= 0u;
		m_refParams.lodMode			= LODMODE_EXACT;
		m_refParams.maxAnisotropy	= min(getPhysicalDeviceProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()).limits.maxSamplerAnisotropy, m_refParams.maxAnisotropy);

		if (m_refParams.mipMap)
		{
			m_refParams.maxLevel	= deLog2Floor32(ANISOTROPY_TEST_RESOLUTION);
			m_refParams.minLod		= 0.0f;
			m_refParams.maxLod		= static_cast<float>(m_refParams.maxLevel);
		}
		else
			m_refParams.maxLevel	= 0;
	}

	tcu::TestStatus	iterate	(void)
	{
		TextureRenderer	renderer	(m_context, VK_SAMPLE_COUNT_1_BIT, ANISOTROPY_TEST_RESOLUTION, ANISOTROPY_TEST_RESOLUTION);
		TestTexture2DSp	texture		= TestTexture2DSp(new pipeline::TestTexture2D(vk::mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM), ANISOTROPY_TEST_RESOLUTION, ANISOTROPY_TEST_RESOLUTION));

		for (int levelNdx = 0; levelNdx < m_refParams.maxLevel + 1; levelNdx++)
		{
			const int gridSize = max(texture->getLevel(levelNdx, 0).getHeight() / 8, 1);
			tcu::fillWithGrid(texture->getLevel(levelNdx, 0), gridSize, Vec4(0.0f, 0.0f, 0.0f, 1.0f), Vec4(1.0f));
		}

		renderer.setViewport(0.0f, 0.0f, static_cast<float>(ANISOTROPY_TEST_RESOLUTION), static_cast<float>(ANISOTROPY_TEST_RESOLUTION));
		renderer.add2DTexture(texture, VK_IMAGE_ASPECT_COLOR_BIT);

		{
			Surface			renderedFrame			(ANISOTROPY_TEST_RESOLUTION, ANISOTROPY_TEST_RESOLUTION);
			Surface			renderedAnisotropyFrame	(ANISOTROPY_TEST_RESOLUTION, ANISOTROPY_TEST_RESOLUTION);
			const float		position[]				=
			{
				-3.5f, -1.0f, 0.0f, 3.5f,
				-3.5f, +1.0f, 0.0f, 1.0f,
				+3.5f, -1.0f, 0.0f, 3.5f,
				+3.5f, +1.0f, 0.0f, 1.0f
			};
			vector<float>	texCoord;

			computeQuadTexCoord2D(texCoord, Vec2(0.0f), Vec2(1.0f));

			renderer.renderQuad(renderedFrame,				position, 0, &texCoord[0], m_refParams, 1.0f);
			renderer.renderQuad(renderedAnisotropyFrame,	position, 0, &texCoord[0], m_refParams, m_refParams.maxAnisotropy);

			if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Expecting comparison to pass", "Expecting comparison to pass",
					renderedFrame.getAccess(), renderedAnisotropyFrame.getAccess(), 0.05f, tcu::COMPARE_LOG_RESULT))
				return tcu::TestStatus::fail("Fail");

			// Anisotropic filtering is implementation dependent. Expecting differences with minification/magnification filter set to NEAREST is too strict.
			// The specification does not require that your aniso & bi-linear filtering are different even in LINEAR, but this check is 'generally' going
			// to detect *some* difference and possibly be useful in catching issues where an implementation hasn't setup their filtering modes correctly.
			if (m_refParams.minFilter != tcu::Sampler::NEAREST && m_refParams.magFilter != tcu::Sampler::NEAREST)
			{
				if (floatThresholdCompare (m_context.getTestContext().getLog(), "Expecting comparison to fail", "Expecting comparison to fail",
							   renderedFrame.getAccess(), renderedAnisotropyFrame.getAccess(), Vec4(0.02f), tcu::COMPARE_LOG_RESULT))
					return tcu::TestStatus::fail("Fail");
			}
		}
		return tcu::TestStatus::pass("Pass");
	}

private:
	 AnisotropyParams m_refParams;
};

class FilteringAnisotropyTests : public vkt::TestCase
{
public:
					FilteringAnisotropyTests	(tcu::TestContext&			testCtx,
												 const string&				name,
												 const string&				description,
												 const AnisotropyParams&	refParams)
		: vkt::TestCase		(testCtx, name, description)
		, m_refParams		(refParams)
	{
	}

	void			initPrograms				(SourceCollections&	programCollection) const
	{
		std::vector<util::Program>	programs;
		programs.push_back(util::PROGRAM_2D_FLOAT);
		initializePrograms(programCollection,glu::PRECISION_HIGHP, programs);
	}

	TestInstance*	createInstance				(Context&	context) const
	{
		return new FilteringAnisotropyInstance(context, m_refParams);
	}

	virtual void	checkSupport				(Context&	context) const
	{
		// Check device for anisotropic filtering support.
		if (!context.getDeviceFeatures().samplerAnisotropy)
			TCU_THROW(NotSupportedError, "Skipping anisotropic tests since the device does not support anisotropic filtering.");
	}

private :
	const AnisotropyParams	m_refParams;
};

} // anonymous

tcu::TestCaseGroup* createFilteringAnisotropyTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup>	filteringAnisotropyTests	(new tcu::TestCaseGroup(testCtx,	"filtering_anisotropy",	"Filtering anisotropy tests"));
	de::MovePtr<tcu::TestCaseGroup>	basicTests					(new tcu::TestCaseGroup(testCtx, "basic", "Filtering anisotropy tests"));
	de::MovePtr<tcu::TestCaseGroup>	mipmapTests					(new tcu::TestCaseGroup(testCtx, "mipmap", "Filtering anisotropy tests"));
	const char*						valueName[]					=
	{
		"anisotropy_2",
		"anisotropy_4",
		"anisotropy_8",
		"anisotropy_max"
	};
	const float						maxAnisotropy[]				=
	{
		2.0f,
		4.0f,
		8.0f,
		10000.0f	//too huge will be flated to max value
	};
	const char*						magFilterName[]				=
	{
		"nearest",
		"linear"
	};
	const tcu::Sampler::FilterMode	magFilters[]				=
	{
		Sampler::NEAREST,
		Sampler::LINEAR
	};

	{
		const tcu::Sampler::FilterMode*	minFilters		= magFilters;
		const char**					minFilterName	= magFilterName;

		for (int anisotropyNdx = 0; anisotropyNdx < DE_LENGTH_OF_ARRAY(maxAnisotropy); anisotropyNdx++)
		{
			de::MovePtr<tcu::TestCaseGroup> levelAnisotropyGroups (new tcu::TestCaseGroup(testCtx, valueName[anisotropyNdx], "Filtering anisotropy tests"));

			for (int minFilterNdx = 0; minFilterNdx < DE_LENGTH_OF_ARRAY(magFilters); minFilterNdx++)
			for (int magFilterNdx = 0; magFilterNdx < DE_LENGTH_OF_ARRAY(magFilters); magFilterNdx++)
			{
				AnisotropyParams	refParams	(TEXTURETYPE_2D, maxAnisotropy[anisotropyNdx] ,minFilters[minFilterNdx], magFilters[magFilterNdx]);
				levelAnisotropyGroups->addChild(new FilteringAnisotropyTests(testCtx,
														"mag_" + string(magFilterName[magFilterNdx]) + "_min_" + string(minFilterName[minFilterNdx]),
														"Texture filtering anisotropy basic tests", refParams));
			}
			basicTests->addChild(levelAnisotropyGroups.release());
		}
		filteringAnisotropyTests->addChild(basicTests.release());
	}

	{
		const tcu::Sampler::FilterMode		minFilters[]	=
		{
			Sampler::NEAREST_MIPMAP_NEAREST,
			Sampler::NEAREST_MIPMAP_LINEAR,
			Sampler::LINEAR_MIPMAP_NEAREST,
			Sampler::LINEAR_MIPMAP_LINEAR
		};
		const char*							minFilterName[]	=
		{
			"nearest_mipmap_nearest",
			"nearest_mipmap_linear",
			"linear_mipmap_nearest",
			"linear_mipmap_linear"
		};

		for (int anisotropyNdx = 0; anisotropyNdx < DE_LENGTH_OF_ARRAY(maxAnisotropy); anisotropyNdx++)
		{
			de::MovePtr<tcu::TestCaseGroup> levelAnisotropyGroups (new tcu::TestCaseGroup(testCtx, valueName[anisotropyNdx], "Filtering anisotropy tests"));

			for (int minFilterNdx = 0; minFilterNdx < DE_LENGTH_OF_ARRAY(minFilters); minFilterNdx++)
			for (int magFilterNdx = 0; magFilterNdx < DE_LENGTH_OF_ARRAY(magFilters); magFilterNdx++)
			{
				AnisotropyParams	refParams	(TEXTURETYPE_2D, maxAnisotropy[anisotropyNdx] ,minFilters[minFilterNdx], magFilters[magFilterNdx], true);
				levelAnisotropyGroups->addChild(new FilteringAnisotropyTests(testCtx,
														"mag_" + string(magFilterName[magFilterNdx]) + "_min_" + string(minFilterName[minFilterNdx]),
														"Texture filtering anisotropy basic tests", refParams));
			}
			mipmapTests->addChild(levelAnisotropyGroups.release());
		}
		filteringAnisotropyTests->addChild(mipmapTests.release());
	}

	return filteringAnisotropyTests.release();
}

} // texture
} // vkt
