/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2016 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
 * \brief GPU image sample verification
 *//*--------------------------------------------------------------------*/

#include "vktSampleVerifier.hpp"
#include "vktSampleVerifierUtil.hpp"

#include "deMath.h"
#include "tcuFloat.hpp"
#include "tcuTextureUtil.hpp"
#include "vkImageUtil.hpp"

#include <fstream>
#include <sstream>

namespace vkt
{
namespace texture
{

using namespace vk;
using namespace tcu;
using namespace util;

namespace
{

int calcUnnormalizedDim (const ImgDim dim)
{
	if (dim == IMG_DIM_1D)
	{
	    return 1;
	}
	else if (dim == IMG_DIM_2D || dim == IMG_DIM_CUBE)
	{
	    return 2;
	}
	else
	{
	    return 3;
	}
}

} // anonymous

SampleVerifier::SampleVerifier (const ImageViewParameters&						imParams,
								const SamplerParameters&						samplerParams,
								const SampleLookupSettings&						sampleLookupSettings,
								int												coordBits,
								int												mipmapBits,
								const std::vector<tcu::FloatFormat>&			conversionPrecision,
								const std::vector<tcu::FloatFormat>&			filteringPrecision,
								const std::vector<tcu::ConstPixelBufferAccess>&	levels)
	: m_imParams				(imParams)
	, m_samplerParams			(samplerParams)
	, m_sampleLookupSettings	(sampleLookupSettings)
	, m_coordBits				(coordBits)
	, m_mipmapBits				(mipmapBits)
	, m_conversionPrecision		(conversionPrecision)
	, m_filteringPrecision		(filteringPrecision)
	, m_unnormalizedDim			(calcUnnormalizedDim(imParams.dim))
	, m_levels					(levels)
{

}

bool SampleVerifier::coordOutOfRange (const IVec3& coord, int compNdx, int level) const
{
	DE_ASSERT(compNdx >= 0 && compNdx < 3);

	return coord[compNdx] < 0 || coord[compNdx] >= m_levels[level].getSize()[compNdx];
}

void SampleVerifier::fetchTexelWrapped (const IVec3&	coord,
										int				layer,
										int				level,
										Vec4&			resultMin,
										Vec4&			resultMax) const
{
    const void* pixelPtr = DE_NULL;

	if (m_imParams.dim == IMG_DIM_1D)
	{
	    pixelPtr = m_levels[level].getPixelPtr(coord[0], layer, 0);
	}
	else if (m_imParams.dim == IMG_DIM_2D || m_imParams.dim == IMG_DIM_CUBE)
	{
		pixelPtr = m_levels[level].getPixelPtr(coord[0], coord[1], layer);
	}
	else
	{
		pixelPtr = m_levels[level].getPixelPtr(coord[0], coord[1], coord[2]);
	}

	convertFormat(pixelPtr, mapVkFormat(m_imParams.format), m_conversionPrecision, resultMin, resultMax);

#if defined(DE_DEBUG)
	// Make sure tcuTexture agrees
	const tcu::ConstPixelBufferAccess&	levelAccess	= m_levels[level];
	const tcu::Vec4						refPix		= (m_imParams.dim == IMG_DIM_1D) ? levelAccess.getPixel(coord[0], layer, 0)
													: (m_imParams.dim == IMG_DIM_2D || m_imParams.dim == IMG_DIM_CUBE) ? levelAccess.getPixel(coord[0], coord[1], layer)
													: levelAccess.getPixel(coord[0], coord[1], coord[2]);

	for (int c = 0; c < 4; c++)
		DE_ASSERT(de::inRange(refPix[c], resultMin[c], resultMax[c]));
#endif
}

void SampleVerifier::fetchTexel (const IVec3&	coordIn,
								 int			layer,
								 int			level,
								 VkFilter		filter,
								 Vec4&			resultMin,
								 Vec4&			resultMax) const
{
	IVec3 coord = coordIn;

	VkSamplerAddressMode wrappingModes[] =
	{
		m_samplerParams.wrappingModeU,
		m_samplerParams.wrappingModeV,
		m_samplerParams.wrappingModeW
	};

	const bool isSrgb = isSrgbFormat(m_imParams.format);

	// Wrapping operations


	if (m_imParams.dim == IMG_DIM_CUBE && filter == VK_FILTER_LINEAR)
	{
		// If the image is a cubemap and we are using linear filtering, we do edge or corner wrapping

		const int	arrayLayer = layer / 6;
		int			arrayFace  = layer % 6;

		if (coordOutOfRange(coord, 0, level) != coordOutOfRange(coord, 1, level))
		{
			// Wrap around edge

			IVec2	newCoord(0);
			int		newFace = 0;

			wrapCubemapEdge(coord.swizzle(0, 1),
							m_levels[level].getSize().swizzle(0, 1),
							arrayFace,
							newCoord,
							newFace);

			coord.xy()	= newCoord;
			layer		= arrayLayer * 6 + newFace;
		}
		else if (coordOutOfRange(coord, 0, level) && coordOutOfRange(coord, 1, level))
		{
			// Wrap corner

			int   faces[3] = {arrayFace, 0, 0};
			IVec2 cornerCoords[3];

			wrapCubemapCorner(coord.swizzle(0, 1),
							  m_levels[level].getSize().swizzle(0, 1),
							  arrayFace,
							  faces[1],
							  faces[2],
							  cornerCoords[0],
							  cornerCoords[1],
							  cornerCoords[2]);

			// \todo [2016-08-01 collinbaker] Call into fetchTexelWrapped instead

			Vec4 cornerTexels[3];

			for (int ndx = 0; ndx < 3; ++ndx)
			{
				int cornerLayer = faces[ndx] + arrayLayer * 6;

				if (isSrgb)
				{
				    cornerTexels[ndx] += sRGBToLinear(m_levels[level].getPixel(cornerCoords[ndx][0], cornerCoords[ndx][1], cornerLayer));
				}
				else
				{
					cornerTexels[ndx] += m_levels[level].getPixel(cornerCoords[ndx][0], cornerCoords[ndx][1], cornerLayer);
				}
			}

			for (int compNdx = 0; compNdx < 4; ++compNdx)
			{
				float compMin = cornerTexels[0][compNdx];
				float compMax = cornerTexels[0][compNdx];

				for (int ndx = 1; ndx < 3; ++ndx)
				{
					const float comp = cornerTexels[ndx][compNdx];

					compMin = de::min(comp, compMin);
					compMax = de::max(comp, compMax);
				}

				resultMin[compNdx] = compMin;
				resultMax[compNdx] = compMax;
			}

			return;
		}
		else
		{
			// If no wrapping is necessary, just do nothing
		}
	}
	else
	{
		// Otherwise, we do normal wrapping

		if (m_imParams.dim == IMG_DIM_CUBE)
		{
			wrappingModes[0] = wrappingModes[1] = wrappingModes[2] = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
		}

		for (int compNdx = 0; compNdx < 3; ++compNdx)
		{
			const int size = m_levels[level].getSize()[compNdx];

			coord[compNdx] = wrapTexelCoord(coord[compNdx], size, wrappingModes[compNdx]);
		}
	}

	if (coordOutOfRange(coord, 0, level) ||
		coordOutOfRange(coord, 1, level) ||
		coordOutOfRange(coord, 2, level))
	{
		// If after wrapping coordinates are still out of range, perform texel replacement

		switch (m_samplerParams.borderColor)
		{
			case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
			{
				resultMin = Vec4(0.0f, 0.0f, 0.0f, 0.0f);
				resultMax = Vec4(0.0f, 0.0f, 0.0f, 0.0f);
				return;
			}
			case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
			{
				resultMin = Vec4(0.0f, 0.0f, 0.0f, 1.0f);
				resultMax = Vec4(0.0f, 0.0f, 0.0f, 1.0f);
				return;
			}
			case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
			{
				resultMin = Vec4(1.0f, 1.0f, 1.0f, 1.0f);
				resultMax = Vec4(1.0f, 1.0f, 1.0f, 1.0f);
				return;
			}
			default:
			{
				// \\ [2016-07-07 collinbaker] Handle
				// VK_BORDER_COLOR_INT_* borders
				DE_FATAL("Not implemented");
				break;
			}
		}
	}
	else
	{
		// Otherwise, actually fetch a texel

	    fetchTexelWrapped(coord, layer, level, resultMin, resultMax);
	}
}

void SampleVerifier::getFilteredSample1D (const IVec3&	texelBase,
										  float			weight,
										  int			layer,
										  int			level,
										  Vec4&			resultMin,
										  Vec4&			resultMax) const
{
	Vec4 texelsMin[2];
	Vec4 texelsMax[2];

	for (int i = 0; i < 2; ++i)
	{
	    fetchTexel(texelBase + IVec3(i, 0, 0), layer, level, VK_FILTER_LINEAR, texelsMin[i], texelsMax[i]);
	}

	for (int compNdx = 0; compNdx < 4; ++compNdx)
	{
		Interval resultInterval(0.0);

		for (int i = 0; i < 2; ++i)
		{
			const Interval	weightInterval	= m_filteringPrecision[compNdx].roundOut(Interval(i == 0 ? 1.0f - weight : weight), false);
			const Interval	texelInterval	(false, texelsMin[i][compNdx], texelsMax[i][compNdx]);

			resultInterval = m_filteringPrecision[compNdx].roundOut(resultInterval + weightInterval * texelInterval, false);
		}

		resultMin[compNdx] = (float)resultInterval.lo();
		resultMax[compNdx] = (float)resultInterval.hi();
	}
}

void SampleVerifier::getFilteredSample2D (const IVec3&	texelBase,
										  const Vec2&	weights,
										  int			layer,
										  int			level,
										  Vec4&			resultMin,
										  Vec4&			resultMax) const
{
	Vec4 texelsMin[4];
	Vec4 texelsMax[4];

	for (int i = 0; i < 2; ++i)
	{
		for (int j = 0; j < 2; ++j)
		{
		    fetchTexel(texelBase + IVec3(i, j, 0), layer, level, VK_FILTER_LINEAR, texelsMin[2 * j + i], texelsMax[2 * j + i]);
		}
	}

	for (int compNdx = 0; compNdx < 4; ++compNdx)
	{
		Interval resultInterval(0.0);

		for (int i = 0; i < 2; ++i)
		{
			const Interval iWeightInterval = m_filteringPrecision[compNdx].roundOut(Interval(i == 0 ? 1.0f - weights[1] : weights[1]), false);

			for (int j = 0; j < 2; ++j)
			{
				const Interval jWeightInterval = m_filteringPrecision[compNdx].roundOut(iWeightInterval * Interval(j == 0 ? 1.0f - weights[0] : weights[0]), false);
				const Interval texelInterval(false, texelsMin[2 * i + j][compNdx], texelsMax[2 * i + j][compNdx]);

				resultInterval = m_filteringPrecision[compNdx].roundOut(resultInterval + jWeightInterval * texelInterval, false);
			}
		}

		resultMin[compNdx] = (float)resultInterval.lo();
		resultMax[compNdx] = (float)resultInterval.hi();
	}
}

void SampleVerifier::getFilteredSample3D (const IVec3&	texelBase,
										  const Vec3&	weights,
										  int			layer,
										  int			level,
										  Vec4&			resultMin,
										  Vec4&			resultMax) const
{
	Vec4 texelsMin[8];
	Vec4 texelsMax[8];

	for (int i = 0; i < 2; ++i)
	{
		for (int j = 0; j < 2; ++j)
		{
			for (int k = 0; k < 2; ++k)
			{
			    fetchTexel(texelBase + IVec3(i, j, k), layer, level, VK_FILTER_LINEAR, texelsMin[4 * k + 2 * j + i], texelsMax[4 * k + 2 * j + i]);
			}
		}
	}

	for (int compNdx = 0; compNdx < 4; ++compNdx)
	{
		Interval resultInterval(0.0);

		for (int i = 0; i < 2; ++i)
		{
			const Interval iWeightInterval = m_filteringPrecision[compNdx].roundOut(Interval(i == 0 ? 1.0f - weights[2] : weights[2]), false);

			for (int j = 0; j < 2; ++j)
			{
				const Interval jWeightInterval = m_filteringPrecision[compNdx].roundOut(iWeightInterval * Interval(j == 0 ? 1.0f - weights[1] : weights[1]), false);

				for (int k = 0; k < 2; ++k)
				{
					const Interval kWeightInterval = m_filteringPrecision[compNdx].roundOut(jWeightInterval * Interval(k == 0 ? 1.0f - weights[0] : weights[0]), false);

					const Interval texelInterval(false, texelsMin[4 * i + 2 * j + k][compNdx], texelsMax[4 * i + 2 * j + k][compNdx]);

					resultInterval = m_filteringPrecision[compNdx].roundOut(resultInterval + kWeightInterval * texelInterval, false);
				}
			}
		}

		resultMin[compNdx] = (float)resultInterval.lo();
		resultMax[compNdx] = (float)resultInterval.hi();
	}
}

void SampleVerifier::getFilteredSample (const IVec3&	texelBase,
										const Vec3&		weights,
										int				layer,
										int				level,
										Vec4&			resultMin,
										Vec4&			resultMax) const
{
	DE_ASSERT(layer < m_imParams.arrayLayers);
	DE_ASSERT(level < m_imParams.levels);

	if (m_imParams.dim == IMG_DIM_1D)
	{
		getFilteredSample1D(texelBase, weights.x(), layer, level, resultMin, resultMax);
	}
	else if (m_imParams.dim == IMG_DIM_2D || m_imParams.dim == IMG_DIM_CUBE)
	{
		getFilteredSample2D(texelBase, weights.swizzle(0, 1), layer, level, resultMin, resultMax);
	}
	else
	{
		getFilteredSample3D(texelBase, weights, layer, level, resultMin, resultMax);
	}
}

void SampleVerifier::getMipmapStepBounds (const Vec2&	lodFracBounds,
										  deInt32&		stepMin,
										  deInt32&		stepMax) const
{
	DE_ASSERT(m_mipmapBits < 32);
	const int mipmapSteps = ((int)1) << m_mipmapBits;

	stepMin = deFloorFloatToInt32(lodFracBounds[0] * (float)mipmapSteps);
	stepMax = deCeilFloatToInt32 (lodFracBounds[1] * (float)mipmapSteps);

	stepMin = de::max(stepMin, (deInt32)0);
	stepMax = de::min(stepMax, (deInt32)mipmapSteps);
}

bool SampleVerifier::verifySampleFiltered (const Vec4&			result,
										   const IVec3&			baseTexelHiIn,
										   const IVec3&			baseTexelLoIn,
										   const IVec3&			texelGridOffsetHiIn,
										   const IVec3&			texelGridOffsetLoIn,
										   int					layer,
										   int					levelHi,
										   const Vec2&			lodFracBounds,
										   VkFilter				filter,
										   VkSamplerMipmapMode	mipmapFilter,
										   std::ostream&		report) const
{
	DE_ASSERT(layer < m_imParams.arrayLayers);
	DE_ASSERT(levelHi < m_imParams.levels);

	const int	coordSteps			= 1 << m_coordBits;
	const int	lodSteps			= 1 << m_mipmapBits;
	const int	levelLo				= (levelHi < m_imParams.levels - 1) ? levelHi + 1 : levelHi;

	IVec3		baseTexelHi			= baseTexelHiIn;
	IVec3		baseTexelLo			= baseTexelLoIn;
	IVec3		texelGridOffsetHi	= texelGridOffsetHiIn;
	IVec3		texelGridOffsetLo	= texelGridOffsetLoIn;
	deInt32		lodStepsMin			= 0;
	deInt32		lodStepsMax			= 0;

	getMipmapStepBounds(lodFracBounds, lodStepsMin, lodStepsMax);

	report << "Testing at base texel " << baseTexelHi << ", " << baseTexelLo << " offset " << texelGridOffsetHi << ", " << texelGridOffsetLo << "\n";

	Vec4 idealSampleHiMin;
	Vec4 idealSampleHiMax;
	Vec4 idealSampleLoMin;
	Vec4 idealSampleLoMax;

	// Get ideal samples at steps at each mipmap level

	if (filter == VK_FILTER_LINEAR)
	{
		// Adjust texel grid coordinates for linear filtering
		wrapTexelGridCoordLinear(baseTexelHi, texelGridOffsetHi, m_coordBits, m_imParams.dim);

		if (mipmapFilter == VK_SAMPLER_MIPMAP_MODE_LINEAR)
		{
			wrapTexelGridCoordLinear(baseTexelLo, texelGridOffsetLo, m_coordBits, m_imParams.dim);
		}

		const Vec3 roundedWeightsHi = texelGridOffsetHi.asFloat() / (float)coordSteps;
		const Vec3 roundedWeightsLo = texelGridOffsetLo.asFloat() / (float)coordSteps;

		report << "Computed weights: " << roundedWeightsHi << ", " << roundedWeightsLo << "\n";

	    getFilteredSample(baseTexelHi, roundedWeightsHi, layer, levelHi, idealSampleHiMin, idealSampleHiMax);

		report << "Ideal hi sample: " << idealSampleHiMin << " through " << idealSampleHiMax << "\n";

		if (mipmapFilter == VK_SAMPLER_MIPMAP_MODE_LINEAR)
		{
		    getFilteredSample(baseTexelLo, roundedWeightsLo, layer, levelLo, idealSampleLoMin, idealSampleLoMax);

			report << "Ideal lo sample: " << idealSampleLoMin << " through " << idealSampleLoMax << "\n";
		}
	}
	else
	{
	    fetchTexel(baseTexelHi, layer, levelHi, VK_FILTER_NEAREST, idealSampleHiMin, idealSampleHiMax);

		report << "Ideal hi sample: " << idealSampleHiMin << " through " << idealSampleHiMax << "\n";

		if (mipmapFilter == VK_SAMPLER_MIPMAP_MODE_LINEAR)
		{
		    fetchTexel(baseTexelLo, layer, levelLo, VK_FILTER_NEAREST, idealSampleLoMin, idealSampleLoMax);

			report << "Ideal lo sample: " << idealSampleLoMin << " through " << idealSampleLoMax << "\n";
		}
	}

	// Test ideal samples based on mipmap filtering mode

	if (mipmapFilter == VK_SAMPLER_MIPMAP_MODE_LINEAR)
	{
		for (deInt32 lodStep = lodStepsMin; lodStep <= lodStepsMax; ++lodStep)
		{
			float weight = (float)lodStep / (float)lodSteps;

			report << "Testing at mipmap weight " << weight << "\n";

			Vec4 idealSampleMin;
			Vec4 idealSampleMax;

			for (int compNdx = 0; compNdx < 4; ++compNdx)
			{
				const Interval idealSampleLo(false, idealSampleLoMin[compNdx], idealSampleLoMax[compNdx]);
				const Interval idealSampleHi(false, idealSampleHiMin[compNdx], idealSampleHiMax[compNdx]);

				const Interval idealSample
					= m_filteringPrecision[compNdx].roundOut(Interval(weight) * idealSampleLo + Interval(1.0f - weight) * idealSampleHi, false);

				idealSampleMin[compNdx] = (float)idealSample.lo();
				idealSampleMax[compNdx] = (float)idealSample.hi();
			}

			report << "Ideal sample: " << idealSampleMin << " through " << idealSampleMax << "\n";

			if (isInRange(result, idealSampleMin, idealSampleMax))
			{
				return true;
			}
			else
			{
				report << "Failed comparison\n";
			}
		}
	}
	else
	{
		if (isInRange(result, idealSampleHiMin, idealSampleHiMax))
		{
			return true;
		}
		else
		{
			report << "Failed comparison\n";
		}
	}

	return false;
}

bool SampleVerifier::verifySampleTexelGridCoords (const SampleArguments&	args,
												  const Vec4&				result,
												  const IVec3&				gridCoordHi,
												  const IVec3&				gridCoordLo,
												  const Vec2&				lodBounds,
												  int						level,
												  VkSamplerMipmapMode		mipmapFilter,
												  std::ostream&				report) const
{
	const int	layer		 = m_imParams.isArrayed ? (int)deRoundEven(args.layer) : 0U;
	const IVec3 gridCoord[2] = {gridCoordHi, gridCoordLo};

	IVec3 baseTexel[2];
	IVec3 texelGridOffset[2];

    for (int levelNdx = 0; levelNdx < 2; ++levelNdx)
	{
		calcTexelBaseOffset(gridCoord[levelNdx], m_coordBits, baseTexel[levelNdx], texelGridOffset[levelNdx]);
	}

	const bool	canBeMinified  = lodBounds[1] > 0.0f;
	const bool	canBeMagnified = lodBounds[0] <= 0.0f;

	if (canBeMagnified)
	{
		report << "Trying magnification...\n";

		if (m_samplerParams.magFilter == VK_FILTER_NEAREST)
		{
			report << "Testing against nearest texel at " << baseTexel[0] << "\n";

			Vec4 idealMin;
			Vec4 idealMax;

			fetchTexel(baseTexel[0], layer, level, VK_FILTER_NEAREST, idealMin, idealMax);

			if (isInRange(result, idealMin, idealMax))
		    {
				return true;
			}
			else
			{
				report << "Failed against " << idealMin << " through " << idealMax << "\n";
			}
		}
		else
		{
			if  (verifySampleFiltered(result, baseTexel[0], baseTexel[1], texelGridOffset[0], texelGridOffset[1], layer, level, Vec2(0.0f, 0.0f), VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_NEAREST, report))
				return true;
		}
	}

	if (canBeMinified)
	{
		report << "Trying minification...\n";

		if (mipmapFilter == VK_SAMPLER_MIPMAP_MODE_LINEAR)
		{
			const Vec2 lodFracBounds = lodBounds - Vec2((float)level);

			if (verifySampleFiltered(result, baseTexel[0], baseTexel[1], texelGridOffset[0], texelGridOffset[1], layer, level, lodFracBounds, m_samplerParams.minFilter, VK_SAMPLER_MIPMAP_MODE_LINEAR, report))
				return true;
		}
		else if (m_samplerParams.minFilter == VK_FILTER_LINEAR)
		{
		    if (verifySampleFiltered(result, baseTexel[0], baseTexel[1], texelGridOffset[0], texelGridOffset[1], layer, level, Vec2(0.0f, 0.0f), VK_FILTER_LINEAR, VK_SAMPLER_MIPMAP_MODE_NEAREST, report))
				return true;
		}
		else
		{
			report << "Testing against nearest texel at " << baseTexel[0] << "\n";

			Vec4 idealMin;
			Vec4 idealMax;

		    fetchTexel(baseTexel[0], layer, level, VK_FILTER_NEAREST, idealMin, idealMax);

			if (isInRange(result, idealMin, idealMax))
		    {
				return true;
			}
			else
			{
				report << "Failed against " << idealMin << " through " << idealMax << "\n";
			}
		}
	}

	return false;
}

bool SampleVerifier::verifySampleMipmapLevel (const SampleArguments&	args,
											  const Vec4&				result,
											  const Vec4&				coord,
											  const Vec2&				lodBounds,
											  int						level,
											  std::ostream&				report) const
{
	DE_ASSERT(level < m_imParams.levels);

	VkSamplerMipmapMode mipmapFilter = m_samplerParams.mipmapFilter;

	if (level == m_imParams.levels - 1)
	{
		mipmapFilter = VK_SAMPLER_MIPMAP_MODE_NEAREST;
	}

	Vec3	unnormalizedCoordMin[2];
	Vec3	unnormalizedCoordMax[2];
	IVec3	gridCoordMin[2];
	IVec3	gridCoordMax[2];

	const FloatFormat coordFormat(-32, 32, 16, true);

	calcUnnormalizedCoordRange(coord,
							   m_levels[level].getSize(),
							   coordFormat,
							   unnormalizedCoordMin[0],
							   unnormalizedCoordMax[0]);

	calcTexelGridCoordRange(unnormalizedCoordMin[0],
							unnormalizedCoordMax[0],
							m_coordBits,
							gridCoordMin[0],
							gridCoordMax[0]);

	report << "Level " << level << " computed unnormalized coordinate range: [" << unnormalizedCoordMin[0] << ", " << unnormalizedCoordMax[0] << "]\n";
	report << "Level " << level << " computed texel grid coordinate range: [" << gridCoordMin[0] << ", " << gridCoordMax[0] << "]\n";

	if (mipmapFilter == VK_SAMPLER_MIPMAP_MODE_LINEAR)
	{
		calcUnnormalizedCoordRange(coord,
								   m_levels[level+1].getSize(),
								   coordFormat,
								   unnormalizedCoordMin[1],
								   unnormalizedCoordMax[1]);

		calcTexelGridCoordRange(unnormalizedCoordMin[1],
								unnormalizedCoordMax[1],
								m_coordBits,
								gridCoordMin[1],
								gridCoordMax[1]);


		report << "Level " << level+1 << " computed unnormalized coordinate range: [" << unnormalizedCoordMin[1] << " - " << unnormalizedCoordMax[1] << "]\n";
		report << "Level " << level+1 << " computed texel grid coordinate range: [" << gridCoordMin[1] << " - " << gridCoordMax[1] << "]\n";
	}
	else
	{
		unnormalizedCoordMin[1] = unnormalizedCoordMax[1] = Vec3(0.0f);
		gridCoordMin[1] = gridCoordMax[1] = IVec3(0);
	}

	bool done = false;

	IVec3 gridCoord[2] = {gridCoordMin[0], gridCoordMin[1]};

    while (!done)
	{
		if (verifySampleTexelGridCoords(args, result, gridCoord[0], gridCoord[1], lodBounds, level, mipmapFilter, report))
			return true;

		// Get next grid coordinate to test at

		// Represents whether the increment at a position wraps and should "carry" to the next place
		bool carry = true;

		for (int levelNdx = 0; levelNdx < 2; ++levelNdx)
		{
			for (int compNdx = 0; compNdx < 3; ++compNdx)
			{
				if (carry)
				{
					deInt32& comp = gridCoord[levelNdx][compNdx];
				    ++comp;

					if (comp > gridCoordMax[levelNdx][compNdx])
					{
						comp = gridCoordMin[levelNdx][compNdx];
					}
					else
					{
						carry = false;
					}
				}
			}
		}

		done = carry;
	}

	return false;
}

bool SampleVerifier::verifySampleCubemapFace (const SampleArguments&	args,
											  const Vec4&				result,
											  const Vec4&				coord,
											  const Vec4&				dPdx,
											  const Vec4&				dPdy,
											  int						face,
											  std::ostream&				report) const
{
	// Will use this parameter once cubemapping is implemented completely
	DE_UNREF(face);

	Vec2 lodBounds;

	if (m_sampleLookupSettings.lookupLodMode == LOOKUP_LOD_MODE_DERIVATIVES)
	{
		float lodBias = m_samplerParams.lodBias;

		if (m_sampleLookupSettings.hasLodBias)
			lodBias += args.lodBias;

		lodBounds = calcLodBounds(dPdx.swizzle(0, 1, 2),
								  dPdy.swizzle(0, 1, 2),
								  m_imParams.size,
								  lodBias,
								  m_samplerParams.minLod,
								  m_samplerParams.maxLod);
	}
	else
	{
		lodBounds[0] = lodBounds[1] = args.lod;
	}

	DE_ASSERT(lodBounds[0] <= lodBounds[1]);

    const UVec2 levelBounds = calcLevelBounds(lodBounds, m_imParams.levels, m_samplerParams.mipmapFilter);

	for (deUint32 level = levelBounds[0]; level <= levelBounds[1]; ++level)
	{
		report << "Testing at mipmap level " << level << "...\n";

		const Vec2 levelLodBounds = calcLevelLodBounds(lodBounds, level);

		if (verifySampleMipmapLevel(args, result, coord, levelLodBounds, level, report))
		{
			return true;
		}

		report << "Done testing mipmap level " << level << ".\n\n";
	}

	return false;
}

bool SampleVerifier::verifySampleImpl (const SampleArguments&	args,
									   const Vec4&				result,
									   std::ostream&			report) const
{
	// \todo [2016-07-11 collinbaker] Handle depth and stencil formats
	// \todo [2016-07-06 collinbaker] Handle dRef
	DE_ASSERT(m_samplerParams.isCompare == false);

	Vec4	coord	  = args.coord;
	int coordSize = 0;

	if (m_imParams.dim == IMG_DIM_1D)
	{
		coordSize = 1;
	}
	else if (m_imParams.dim == IMG_DIM_2D)
	{
		coordSize = 2;
	}
	else if (m_imParams.dim == IMG_DIM_3D || m_imParams.dim == IMG_DIM_CUBE)
	{
		coordSize = 3;
	}

	// 15.6.1 Project operation

	if (m_sampleLookupSettings.isProjective)
	{
		DE_ASSERT(args.coord[coordSize] != 0.0f);
		const float proj = coord[coordSize];

		coord = coord / proj;
	}

	const Vec4 dPdx = (m_sampleLookupSettings.lookupLodMode == LOOKUP_LOD_MODE_DERIVATIVES) ? args.dPdx : Vec4(0);
	const Vec4 dPdy = (m_sampleLookupSettings.lookupLodMode == LOOKUP_LOD_MODE_DERIVATIVES) ? args.dPdy : Vec4(0);

	// 15.6.3 Cube Map Face Selection and Transformations

	if (m_imParams.dim == IMG_DIM_CUBE)
	{
		const Vec3	r		   = coord.swizzle(0, 1, 2);
		const Vec3	drdx	   = dPdx.swizzle(0, 1, 2);
		const Vec3	drdy	   = dPdy.swizzle(0, 1, 2);

	    int			faceBitmap = calcCandidateCubemapFaces(r);

		// We must test every possible disambiguation order

		for (int faceNdx = 0; faceNdx < 6; ++faceNdx)
		{
			const bool isPossible = ((faceBitmap & (1U << faceNdx)) != 0);

		    if (!isPossible)
			{
				continue;
			}

			Vec2 coordFace;
			Vec2 dPdxFace;
			Vec2 dPdyFace;

			calcCubemapFaceCoords(r, drdx, drdy, faceNdx, coordFace, dPdxFace, dPdyFace);

			if (verifySampleCubemapFace(args,
										result,
										Vec4(coordFace[0], coordFace[1], 0.0f, 0.0f),
										Vec4(dPdxFace[0], dPdxFace[1], 0.0f, 0.0f),
										Vec4(dPdyFace[0], dPdyFace[1], 0.0f, 0.0f),
										faceNdx,
										report))
			{
				return true;
			}
		}

		return false;
	}
	else
	{
		return verifySampleCubemapFace(args, result, coord, dPdx, dPdy, 0, report);
	}
}

bool SampleVerifier::verifySampleReport (const SampleArguments&	args,
										 const Vec4&			result,
										 std::string&			report) const
{
	std::ostringstream reportStream;

	const bool isValid = verifySampleImpl(args, result, reportStream);

	report = reportStream.str();

    return isValid;
}

bool SampleVerifier::verifySample (const SampleArguments&	args,
								   const Vec4&				result) const
{
	// Create unopened ofstream to simulate "null" ostream
	std::ofstream nullStream;

	return verifySampleImpl(args, result, nullStream);
}

} // texture
} // vkt
