Fix missing dependency on sparse binds
[platform/upstream/VK-GL-CTS.git] / framework / common / tcuTexVerifierUtil.cpp
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         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
44 float computeFixedPointError (const int numAccurateBits)
45 {
46         return computeFloatingPointError(1.0f, numAccurateBits);
47 }
48
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
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
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
125 Sampler getUnnormalizedCoordSampler (const Sampler& sampler)
126 {
127         Sampler copy = sampler;
128         copy.normalizedCoords = false;
129         return copy;
130 }
131
132 static inline int imod (int a, int b)
133 {
134         int m = a % b;
135         return m < 0 ? m + b : m;
136 }
137
138 static inline int mirror (int a)
139 {
140         return a >= 0 ? a : -(1 + a);
141 }
142
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