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
computeFloatingPointError(const float value,const int numAccurateBits)32 float computeFloatingPointError (const float value, const int numAccurateBits)
33 {
34 DE_ASSERT(numAccurateBits >= 0);
35 DE_ASSERT(numAccurateBits <= 23);
36
37 const int numGarbageBits = 23-numAccurateBits;
38 const deUint32 mask = (1u<<numGarbageBits)-1u;
39 const int exp = tcu::Float32(value).exponent();
40
41 return Float32::construct(+1, exp, (1u<<23) | mask).asFloat() - Float32::construct(+1, exp, 1u<<23).asFloat();
42 }
43
computeFixedPointError(const int numAccurateBits)44 float computeFixedPointError (const int numAccurateBits)
45 {
46 return computeFloatingPointError(1.0f, numAccurateBits);
47 }
48
computeColorBitsError(const int bits,const int numAccurateBits)49 float computeColorBitsError(const int bits, const int numAccurateBits)
50 {
51 // Color bits error is not a generic function, it just for compute the error value that cannot be accurately shown in integer data format.
52 //
53 // "bits" is color bit width, "numAccurateBits" is the number of accurate bits in color bits, "1 << (bits - numAccurateBits)" is the threshold in integer.
54 // "1.0f / 256.0f" is epsilon value, to make sure the threshold use to calculate in float can be a little bigger than the real value.
55 return (float(1 << (bits - numAccurateBits)) + 1.0f / 256.0f) / float((1 << bits) - 1);
56 }
57
computeNonNormalizedCoordBounds(const bool normalizedCoords,const int dim,const float coord,const int coordBits,const int uvBits)58 Vec2 computeNonNormalizedCoordBounds (const bool normalizedCoords, const int dim, const float coord, const int coordBits, const int uvBits)
59 {
60 const float coordErr = computeFloatingPointError(coord, coordBits);
61 const float minN = coord - coordErr;
62 const float maxN = coord + coordErr;
63 const float minA = normalizedCoords ? minN*float(dim) : minN;
64 const float maxA = normalizedCoords ? maxN*float(dim) : maxN;
65 const float minC = minA - computeFixedPointError(uvBits);
66 const float maxC = maxA + computeFixedPointError(uvBits);
67
68 DE_ASSERT(minC <= maxC);
69
70 return Vec2(minC, maxC);
71 }
72
getPossibleCubeFaces(const Vec3 & coord,const IVec3 & bits,CubeFace * faces,int & numFaces)73 void getPossibleCubeFaces (const Vec3& coord, const IVec3& bits, CubeFace* faces, int& numFaces)
74 {
75 const float x = coord.x();
76 const float y = coord.y();
77 const float z = coord.z();
78 const float ax = de::abs(x);
79 const float ay = de::abs(y);
80 const float az = de::abs(z);
81 const float ex = computeFloatingPointError(x, bits.x());
82 const float ey = computeFloatingPointError(y, bits.y());
83 const float ez = computeFloatingPointError(z, bits.z());
84
85 numFaces = 0;
86
87 if (ay+ey < ax-ex && az+ez < ax-ex)
88 {
89 if (x >= ex) faces[numFaces++] = CUBEFACE_POSITIVE_X;
90 if (x <= ex) faces[numFaces++] = CUBEFACE_NEGATIVE_X;
91 }
92 else if (ax+ex < ay-ey && az+ez < ay-ey)
93 {
94 if (y >= ey) faces[numFaces++] = CUBEFACE_POSITIVE_Y;
95 if (y <= ey) faces[numFaces++] = CUBEFACE_NEGATIVE_Y;
96 }
97 else if (ax+ex < az-ez && ay+ey < az-ez)
98 {
99 if (z >= ez) faces[numFaces++] = CUBEFACE_POSITIVE_Z;
100 if (z <= ez) faces[numFaces++] = CUBEFACE_NEGATIVE_Z;
101 }
102 else
103 {
104 // One or more components are equal (or within error bounds). Allow all faces where major axis is not zero.
105 if (ax > ex)
106 {
107 faces[numFaces++] = CUBEFACE_NEGATIVE_X;
108 faces[numFaces++] = CUBEFACE_POSITIVE_X;
109 }
110
111 if (ay > ey)
112 {
113 faces[numFaces++] = CUBEFACE_NEGATIVE_Y;
114 faces[numFaces++] = CUBEFACE_POSITIVE_Y;
115 }
116
117 if (az > ez)
118 {
119 faces[numFaces++] = CUBEFACE_NEGATIVE_Z;
120 faces[numFaces++] = CUBEFACE_POSITIVE_Z;
121 }
122 }
123 }
124
getUnnormalizedCoordSampler(const Sampler & sampler)125 Sampler getUnnormalizedCoordSampler (const Sampler& sampler)
126 {
127 Sampler copy = sampler;
128 copy.normalizedCoords = false;
129 return copy;
130 }
131
imod(int a,int b)132 static inline int imod (int a, int b)
133 {
134 int m = a % b;
135 return m < 0 ? m + b : m;
136 }
137
mirror(int a)138 static inline int mirror (int a)
139 {
140 return a >= 0 ? a : -(1 + a);
141 }
142
wrap(Sampler::WrapMode mode,int c,int size)143 int wrap (Sampler::WrapMode mode, int c, int size)
144 {
145 switch (mode)
146 {
147 // \note CL and GL modes are handled identically here, as verification process accounts for
148 // accuracy differences caused by different methods (wrapping vs. denormalizing first).
149 case tcu::Sampler::CLAMP_TO_BORDER:
150 return deClamp32(c, -1, size);
151
152 case tcu::Sampler::CLAMP_TO_EDGE:
153 return deClamp32(c, 0, size-1);
154
155 case tcu::Sampler::REPEAT_GL:
156 case tcu::Sampler::REPEAT_CL:
157 return imod(c, size);
158
159 case tcu::Sampler::MIRRORED_ONCE:
160 c = deClamp32(c, -size, size);
161 // Fall-through
162
163 case tcu::Sampler::MIRRORED_REPEAT_GL:
164 case tcu::Sampler::MIRRORED_REPEAT_CL:
165 return (size - 1) - mirror(imod(c, 2*size) - size);
166
167 default:
168 DE_ASSERT(DE_FALSE);
169 return 0;
170 }
171 }
172 } // TexVerifierUtil
173 } // tcu
174