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 27namespace tcu 28{ 29namespace TexVerifierUtil 30{ 31 32float 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 41float computeFixedPointError (const int numAccurateBits) 42{ 43 return computeFloatingPointError(1.0f, numAccurateBits); 44} 45 46Vec2 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 61void 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 113Sampler getUnnormalizedCoordSampler (const Sampler& sampler) 114{ 115 Sampler copy = sampler; 116 copy.normalizedCoords = false; 117 return copy; 118} 119 120static inline int imod (int a, int b) 121{ 122 int m = a % b; 123 return m < 0 ? m + b : m; 124} 125 126static inline int mirror (int a) 127{ 128 return a >= 0.0f ? a : -(1 + a); 129} 130 131int 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