/*-------------------------------------------------------------------------
 * 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::ConstPixelBufferAccess>&	pba)
// \todo [2016-07-29 collinbaker] Get rid of magic numbers
	: m_internalFormat			(-14, 15, 10, true) // fp16 format
	, m_imParams				(imParams)
	, m_samplerParams			(samplerParams)
	, m_sampleLookupSettings	(sampleLookupSettings)
	, m_coordBits				(coordBits)
	, m_mipmapBits				(mipmapBits)
	, m_unnormalizedDim			(calcUnnormalizedDim(imParams.dim))
	, m_pba						(pba)
{

}

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

	return coord[compNdx] < 0 || coord[compNdx] >= m_pba[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_pba[level].getPixelPtr(coord[0], layer, 0);
	}
	else if (m_imParams.dim == IMG_DIM_2D || m_imParams.dim == IMG_DIM_CUBE)
	{
		pixelPtr = m_pba[level].getPixelPtr(coord[0], coord[1], layer);
	}
	else
	{
		pixelPtr = m_pba[level].getPixelPtr(coord[0], coord[1], coord[2]);
	}

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

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_pba[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_pba[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_pba[level].getPixel(cornerCoords[ndx][0], cornerCoords[ndx][1], cornerLayer));
				}
				else
				{
					cornerTexels[ndx] += m_pba[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_pba[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]);
	}

	Interval resultIntervals[4];

	for (int ndx = 0; ndx < 4; ++ndx)
	{
		resultIntervals[ndx] = Interval(0.0);
	}

    for (int i = 0; i < 2; ++i)
	{
		const Interval weightInterval = m_internalFormat.roundOut(Interval(i == 0 ? 1.0f - weight : weight), false);

		for (int compNdx = 0; compNdx < 4; ++compNdx)
		{
			const Interval texelInterval(false, texelsMin[i][compNdx], texelsMax[i][compNdx]);

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

	for (int compNdx = 0; compNdx < 4; ++compNdx)
	{
		resultMin[compNdx] = (float)resultIntervals[compNdx].lo();
		resultMax[compNdx] = (float)resultIntervals[compNdx].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]);
		}
	}

	Interval resultIntervals[4];

	for (int ndx = 0; ndx < 4; ++ndx)
	{
		resultIntervals[ndx] = Interval(0.0);
	}

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

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

			for (int compNdx = 0; compNdx < 4; ++compNdx)
			{
				const Interval texelInterval(false, texelsMin[2 * i + j][compNdx], texelsMax[2 * i + j][compNdx]);

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

	for (int compNdx = 0; compNdx < 4; ++compNdx)
	{
		resultMin[compNdx] = (float)resultIntervals[compNdx].lo();
		resultMax[compNdx] = (float)resultIntervals[compNdx].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]);
			}
		}
	}

    Interval resultIntervals[4];

	for (int ndx = 0; ndx < 4; ++ndx)
	{
		resultIntervals[ndx] = Interval(0.0);
	}

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

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

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

				for (int compNdx = 0; compNdx < 4; ++compNdx)
				{
					const Interval texelInterval(false, texelsMin[4 * i + 2 * j + k][compNdx], texelsMax[4 * i + 2 * j + k][compNdx]);

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

	for (int compNdx = 0; compNdx < 4; ++compNdx)
	{
		resultMin[compNdx] = (float)resultIntervals[compNdx].lo();
		resultMax[compNdx] = (float)resultIntervals[compNdx].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_internalFormat.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_pba[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_pba[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
