13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Tester Core
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Internal utilities shared between TexLookup and TexCompare verifiers.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTexVerifierUtil.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuFloat.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace tcu
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace TexVerifierUtil
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat computeFloatingPointError (const float value, const int numAccurateBits)
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		numGarbageBits	= 23-numAccurateBits;
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32	mask			= (1u<<numGarbageBits)-1u;
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		exp				= tcu::Float32(value).exponent();
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return Float32::construct(+1, exp, (1u<<23) | mask).asFloat() - Float32::construct(+1, exp, 1u<<23).asFloat();
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat computeFixedPointError (const int numAccurateBits)
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return computeFloatingPointError(1.0f, numAccurateBits);
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec2 computeNonNormalizedCoordBounds (const bool normalizedCoords, const int dim, const float coord, const int coordBits, const int uvBits)
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		coordErr		= computeFloatingPointError(coord, coordBits);
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		minN			= coord - coordErr;
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		maxN			= coord + coordErr;
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		minA			= normalizedCoords ? minN*float(dim) : minN;
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		maxA			= normalizedCoords ? maxN*float(dim) : maxN;
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		minC			= minA - computeFixedPointError(uvBits);
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		maxC			= maxA + computeFixedPointError(uvBits);
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(minC <= maxC);
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return Vec2(minC, maxC);
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid getPossibleCubeFaces (const Vec3& coord, const IVec3& bits, CubeFace* faces, int& numFaces)
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	x	= coord.x();
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	y	= coord.y();
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	z	= coord.z();
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float ax	= de::abs(x);
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float ay	= de::abs(y);
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float az	= de::abs(z);
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float ex	= computeFloatingPointError(x, bits.x());
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float	ey	= computeFloatingPointError(y, bits.y());
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float ez	= computeFloatingPointError(z, bits.z());
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	numFaces = 0;
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (ay+ey < ax-ex && az+ez < ax-ex)
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (x >= ex) faces[numFaces++] = CUBEFACE_POSITIVE_X;
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (x <= ex) faces[numFaces++] = CUBEFACE_NEGATIVE_X;
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (ax+ex < ay-ey && az+ez < ay-ey)
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (y >= ey) faces[numFaces++] = CUBEFACE_POSITIVE_Y;
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (y <= ey) faces[numFaces++] = CUBEFACE_NEGATIVE_Y;
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (ax+ex < az-ez && ay+ey < az-ez)
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (z >= ez) faces[numFaces++] = CUBEFACE_POSITIVE_Z;
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (z <= ez) faces[numFaces++] = CUBEFACE_NEGATIVE_Z;
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// One or more components are equal (or within error bounds). Allow all faces where major axis is not zero.
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (ax > ex)
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			faces[numFaces++] = CUBEFACE_NEGATIVE_X;
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			faces[numFaces++] = CUBEFACE_POSITIVE_X;
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (ay > ey)
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			faces[numFaces++] = CUBEFACE_NEGATIVE_Y;
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			faces[numFaces++] = CUBEFACE_POSITIVE_Y;
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (az > ez)
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			faces[numFaces++] = CUBEFACE_NEGATIVE_Z;
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			faces[numFaces++] = CUBEFACE_POSITIVE_Z;
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1133c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySampler getUnnormalizedCoordSampler (const Sampler& sampler)
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Sampler copy = sampler;
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	copy.normalizedCoords = false;
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return copy;
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int imod (int a, int b)
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int m = a % b;
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m < 0 ? m + b : m;
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int mirror (int a)
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return a >= 0.0f ? a : -(1 + a);
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint wrap (Sampler::WrapMode mode, int c, int size)
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (mode)
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note CL and GL modes are handled identically here, as verification process accounts for
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		//		 accuracy differences caused by different methods (wrapping vs. denormalizing first).
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_BORDER:
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return deClamp32(c, -1, size);
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::CLAMP_TO_EDGE:
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return deClamp32(c, 0, size-1);
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_GL:
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::REPEAT_CL:
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return imod(c, size);
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_GL:
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::Sampler::MIRRORED_REPEAT_CL:
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (size - 1) - mirror(imod(c, 2*size) - size);
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // TexVerifierUtil
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // tcu
159