/*-------------------------------------------------------------------------
 * 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<de::SharedPtr<tcu::FloatFormat>>&	conversionPrecision,
								const std::vector<de::SharedPtr<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
