Home | History | Annotate | Download | only in common
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program Tester Core
      3  * ----------------------------------------
      4  *
      5  * Copyright 2014 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief Internal utilities shared between TexLookup and TexCompare verifiers.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "tcuTexVerifierUtil.hpp"
     25 #include "tcuFloat.hpp"
     26 
     27 namespace tcu
     28 {
     29 namespace TexVerifierUtil
     30 {
     31 
     32 float computeFloatingPointError (const float value, const int numAccurateBits)
     33 {
     34 	const int		numGarbageBits	= 23-numAccurateBits;
     35 	const deUint32	mask			= (1u<<numGarbageBits)-1u;
     36 	const int		exp				= tcu::Float32(value).exponent();
     37 
     38 	return Float32::construct(+1, exp, (1u<<23) | mask).asFloat() - Float32::construct(+1, exp, 1u<<23).asFloat();
     39 }
     40 
     41 float computeFixedPointError (const int numAccurateBits)
     42 {
     43 	return computeFloatingPointError(1.0f, numAccurateBits);
     44 }
     45 
     46 Vec2 computeNonNormalizedCoordBounds (const bool normalizedCoords, const int dim, const float coord, const int coordBits, const int uvBits)
     47 {
     48 	const float		coordErr		= computeFloatingPointError(coord, coordBits);
     49 	const float		minN			= coord - coordErr;
     50 	const float		maxN			= coord + coordErr;
     51 	const float		minA			= normalizedCoords ? minN*float(dim) : minN;
     52 	const float		maxA			= normalizedCoords ? maxN*float(dim) : maxN;
     53 	const float		minC			= minA - computeFixedPointError(uvBits);
     54 	const float		maxC			= maxA + computeFixedPointError(uvBits);
     55 
     56 	DE_ASSERT(minC <= maxC);
     57 
     58 	return Vec2(minC, maxC);
     59 }
     60 
     61 void getPossibleCubeFaces (const Vec3& coord, const IVec3& bits, CubeFace* faces, int& numFaces)
     62 {
     63 	const float	x	= coord.x();
     64 	const float	y	= coord.y();
     65 	const float	z	= coord.z();
     66 	const float ax	= de::abs(x);
     67 	const float ay	= de::abs(y);
     68 	const float az	= de::abs(z);
     69 	const float ex	= computeFloatingPointError(x, bits.x());
     70 	const float	ey	= computeFloatingPointError(y, bits.y());
     71 	const float ez	= computeFloatingPointError(z, bits.z());
     72 
     73 	numFaces = 0;
     74 
     75 	if (ay+ey < ax-ex && az+ez < ax-ex)
     76 	{
     77 		if (x >= ex) faces[numFaces++] = CUBEFACE_POSITIVE_X;
     78 		if (x <= ex) faces[numFaces++] = CUBEFACE_NEGATIVE_X;
     79 	}
     80 	else if (ax+ex < ay-ey && az+ez < ay-ey)
     81 	{
     82 		if (y >= ey) faces[numFaces++] = CUBEFACE_POSITIVE_Y;
     83 		if (y <= ey) faces[numFaces++] = CUBEFACE_NEGATIVE_Y;
     84 	}
     85 	else if (ax+ex < az-ez && ay+ey < az-ez)
     86 	{
     87 		if (z >= ez) faces[numFaces++] = CUBEFACE_POSITIVE_Z;
     88 		if (z <= ez) faces[numFaces++] = CUBEFACE_NEGATIVE_Z;
     89 	}
     90 	else
     91 	{
     92 		// One or more components are equal (or within error bounds). Allow all faces where major axis is not zero.
     93 		if (ax > ex)
     94 		{
     95 			faces[numFaces++] = CUBEFACE_NEGATIVE_X;
     96 			faces[numFaces++] = CUBEFACE_POSITIVE_X;
     97 		}
     98 
     99 		if (ay > ey)
    100 		{
    101 			faces[numFaces++] = CUBEFACE_NEGATIVE_Y;
    102 			faces[numFaces++] = CUBEFACE_POSITIVE_Y;
    103 		}
    104 
    105 		if (az > ez)
    106 		{
    107 			faces[numFaces++] = CUBEFACE_NEGATIVE_Z;
    108 			faces[numFaces++] = CUBEFACE_POSITIVE_Z;
    109 		}
    110 	}
    111 }
    112 
    113 Sampler getUnnormalizedCoordSampler (const Sampler& sampler)
    114 {
    115 	Sampler copy = sampler;
    116 	copy.normalizedCoords = false;
    117 	return copy;
    118 }
    119 
    120 static inline int imod (int a, int b)
    121 {
    122 	int m = a % b;
    123 	return m < 0 ? m + b : m;
    124 }
    125 
    126 static inline int mirror (int a)
    127 {
    128 	return a >= 0.0f ? a : -(1 + a);
    129 }
    130 
    131 int wrap (Sampler::WrapMode mode, int c, int size)
    132 {
    133 	switch (mode)
    134 	{
    135 		// \note CL and GL modes are handled identically here, as verification process accounts for
    136 		//		 accuracy differences caused by different methods (wrapping vs. denormalizing first).
    137 		case tcu::Sampler::CLAMP_TO_BORDER:
    138 			return deClamp32(c, -1, size);
    139 
    140 		case tcu::Sampler::CLAMP_TO_EDGE:
    141 			return deClamp32(c, 0, size-1);
    142 
    143 		case tcu::Sampler::REPEAT_GL:
    144 		case tcu::Sampler::REPEAT_CL:
    145 			return imod(c, size);
    146 
    147 		case tcu::Sampler::MIRRORED_REPEAT_GL:
    148 		case tcu::Sampler::MIRRORED_REPEAT_CL:
    149 			return (size - 1) - mirror(imod(c, 2*size) - size);
    150 
    151 		default:
    152 			DE_ASSERT(DE_FALSE);
    153 			return 0;
    154 	}
    155 }
    156 
    157 } // TexVerifierUtil
    158 } // tcu
    159