1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES Utilities
3 * ------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 goog
.provide('framework.common.tcuTexVerifierUtil');
23 goog
.require('framework.common.tcuFloat');
24 goog
.require('framework.common.tcuTexture');
25 goog
.require('framework.delibs.debase.deMath');
26 goog
.require('framework.delibs.debase.deUtil');
28 goog
.scope(function() {
30 var tcuTexVerifierUtil
= framework
.common
.tcuTexVerifierUtil
;
31 var deMath
= framework
.delibs
.debase
.deMath
;
32 var deUtil
= framework
.delibs
.debase
.deUtil
;
33 var tcuFloat
= framework
.common
.tcuFloat
;
34 var tcuTexture
= framework
.common
.tcuTexture
;
37 * @param {number} value
38 * @param {number} numAccurateBits
41 tcuTexVerifierUtil
.computeFloatingPointError = function(value
, numAccurateBits
) {
42 /** @type {number} */ var numGarbageBits
= 23 - numAccurateBits
;
43 /** @type {number} */ var mask
= (1 << numGarbageBits
) - 1;
44 /** @type {number} */ var exp
= tcuFloat
.newFloat32(value
).exponent();
46 /** @type {tcuFloat.deFloat} */ var v1
= new tcuFloat
.deFloat();
47 /** @type {tcuFloat.deFloat} */ var v2
= new tcuFloat
.deFloat();
48 return v1
.construct(1, exp
, 1 << 23 | mask
).getValue() - v2
.construct(1, exp
, 1 << 23).getValue();
52 * @param {number} numAccurateBits
55 tcuTexVerifierUtil
.computeFixedPointError = function(numAccurateBits
) {
56 return tcuTexVerifierUtil
.computeFloatingPointError(1.0, numAccurateBits
);
60 * @param {Array<number>} numAccurateBits
61 * @return {Array<number>}
63 tcuTexVerifierUtil
.computeFixedPointError_Vector = function(numAccurateBits
) {
64 /** @type {Array<number>} */ var res
= [];
65 for (var ndx
= 0; ndx
< numAccurateBits
.length
; ndx
++)
66 res
[ndx
] = tcuTexVerifierUtil
.computeFixedPointError(numAccurateBits
[ndx
]);
71 * @param {Array<number>} value
72 * @param {Array<number>} numAccurateBits
73 * @return {Array<number>}
75 tcuTexVerifierUtil
.computeFloatingPointError_Vector = function(value
, numAccurateBits
) {
76 assertMsgOptions(value
.length
=== numAccurateBits
.length
, '', false, true);
77 /** @type {Array<number>} */ var res
= [];
78 for (var ndx
= 0; ndx
< value
.length
; ndx
++)
79 res
[ndx
] = tcuTexVerifierUtil
.computeFloatingPointError(value
[ndx
], numAccurateBits
[ndx
]);
83 // Sampler introspection
86 * @param {tcuTexture.FilterMode} mode
89 tcuTexVerifierUtil
.isNearestMipmapFilter = function(mode
) {
90 return mode
== tcuTexture
.FilterMode
.NEAREST_MIPMAP_NEAREST
|| mode
== tcuTexture
.FilterMode
.LINEAR_MIPMAP_NEAREST
;
94 * @param {tcuTexture.FilterMode} mode
97 tcuTexVerifierUtil
.isLinearMipmapFilter = function(mode
) {
98 return mode
== tcuTexture
.FilterMode
.NEAREST_MIPMAP_LINEAR
|| mode
== tcuTexture
.FilterMode
.LINEAR_MIPMAP_LINEAR
;
102 * @param {tcuTexture.FilterMode} mode
105 tcuTexVerifierUtil
.isMipmapFilter = function(mode
) {
106 return tcuTexVerifierUtil
.isNearestMipmapFilter(mode
) || tcuTexVerifierUtil
.isLinearMipmapFilter(mode
);
110 * @param {tcuTexture.FilterMode} mode
113 tcuTexVerifierUtil
.isLinearFilter = function(mode
) {
114 return mode
== tcuTexture
.FilterMode
.LINEAR
|| mode
== tcuTexture
.FilterMode
.LINEAR_MIPMAP_NEAREST
|| mode
== tcuTexture
.FilterMode
.LINEAR_MIPMAP_LINEAR
;
118 * @param {tcuTexture.FilterMode} mode
121 tcuTexVerifierUtil
.isNearestFilter = function(mode
) {
122 return !tcuTexVerifierUtil
.isLinearFilter(mode
);
126 * @param {tcuTexture.FilterMode} mode
127 * @return {tcuTexture.FilterMode}
129 tcuTexVerifierUtil
.getLevelFilter = function(mode
) {
130 return tcuTexVerifierUtil
.isLinearFilter(mode
) ? tcuTexture
.FilterMode
.LINEAR
: tcuTexture
.FilterMode
.NEAREST
;
134 * @param {tcuTexture.WrapMode} mode
137 tcuTexVerifierUtil
.isWrapModeSupported = function(mode
) {
138 return mode
!= tcuTexture
.WrapMode
.MIRRORED_REPEAT_CL
&& mode
!= tcuTexture
.WrapMode
.REPEAT_CL
;
143 * @param {boolean} normalizedCoords
144 * @param {number} dim
145 * @param {number} coord
146 * @param {number} coordBits
147 * @param {number} uvBits
148 * @return {Array<number>}
150 tcuTexVerifierUtil
.computeNonNormalizedCoordBounds = function(normalizedCoords
, dim
, coord
, coordBits
, uvBits
) {
151 /** @type {number} */ var coordErr
= tcuTexVerifierUtil
.computeFloatingPointError(coord
, coordBits
);
152 /** @type {number} */ var minN
= coord
- coordErr
;
153 /** @type {number} */ var maxN
= coord
+ coordErr
;
154 /** @type {number} */ var minA
= normalizedCoords
? minN
* dim
: minN
;
155 /** @type {number} */ var maxA
= normalizedCoords
? maxN
* dim
: maxN
;
156 /** @type {number} */ var minC
= minA
- tcuTexVerifierUtil
.computeFixedPointError(uvBits
);
157 /** @type {number} */ var maxC
= maxA
+ tcuTexVerifierUtil
.computeFixedPointError(uvBits
);
158 assertMsgOptions(minC
<= maxC
, '', false, true);
163 * @param {Array<number>} coord
164 * @param {Array<number>} bits
165 * @return {?Array<tcuTexture.CubeFace>}
167 tcuTexVerifierUtil
.getPossibleCubeFaces = function(coord
, bits
) {
169 /** @type {Array<tcuTexture.CubeFace>} */ var faces
= [];
171 /** @type {number} */ var x
= coord
[0];
172 /** @type {number} */ var y
= coord
[1];
173 /** @type {number} */ var z
= coord
[2];
174 /** @type {number} */ var ax
= Math
.abs(x
);
175 /** @type {number} */ var ay
= Math
.abs(y
);
176 /** @type {number} */ var az
= Math
.abs(z
);
177 /** @type {number} */ var ex
= tcuTexVerifierUtil
.computeFloatingPointError(x
, bits
[0]);
178 /** @type {number} */ var ey
= tcuTexVerifierUtil
.computeFloatingPointError(y
, bits
[1]);
179 /** @type {number} */ var ez
= tcuTexVerifierUtil
.computeFloatingPointError(z
, bits
[2]);
180 /** @type {number} */ var numFaces
= 0;
182 if (ay
+ ey
< ax
- ex
&& az
+ ez
< ax
- ex
) {
183 if (x
>= ex
) faces
.push(tcuTexture
.CubeFace
.CUBEFACE_POSITIVE_X
);
184 if (x
<= ex
) faces
.push(tcuTexture
.CubeFace
.CUBEFACE_NEGATIVE_X
);
185 } else if (ax
+ ex
< ay
- ey
&& az
+ ez
< ay
- ey
) {
186 if (y
>= ey
) faces
.push(tcuTexture
.CubeFace
.CUBEFACE_POSITIVE_Y
);
187 if (y
<= ey
) faces
.push(tcuTexture
.CubeFace
.CUBEFACE_NEGATIVE_Y
);
188 } else if (ax
+ ex
< az
- ez
&& ay
+ ey
< az
- ez
) {
189 if (z
>= ez
) faces
.push(tcuTexture
.CubeFace
.CUBEFACE_POSITIVE_Z
);
190 if (z
<= ez
) faces
.push(tcuTexture
.CubeFace
.CUBEFACE_NEGATIVE_Z
);
192 // One or more components are equal (or within error bounds). Allow all faces where major axis is not zero.
194 faces
.push(tcuTexture
.CubeFace
.CUBEFACE_NEGATIVE_X
);
195 faces
.push(tcuTexture
.CubeFace
.CUBEFACE_POSITIVE_X
);
199 faces
.push(tcuTexture
.CubeFace
.CUBEFACE_NEGATIVE_Y
);
200 faces
.push(tcuTexture
.CubeFace
.CUBEFACE_POSITIVE_Y
);
204 faces
.push(tcuTexture
.CubeFace
.CUBEFACE_NEGATIVE_Z
);
205 faces
.push(tcuTexture
.CubeFace
.CUBEFACE_POSITIVE_Z
);
209 return faces
.length
== 0 ? null : faces
;
213 * @param {tcuTexture.Sampler} sampler
214 * @return {tcuTexture.Sampler}
216 tcuTexVerifierUtil
.getUnnormalizedCoordSampler = function(sampler
) {
217 var copy
= /** @type {tcuTexture.Sampler} */ (deUtil
.clone(sampler
));
218 copy
.normalizedCoords
= false;
227 tcuTexVerifierUtil
.imod = function(a
, b
) {
228 return deMath
.imod(a
, b
);
235 tcuTexVerifierUtil
.mirror = function(a
) {
236 return deMath
.mirror(a
);
240 * @param {tcuTexture.WrapMode} mode
242 * @param {number} size
245 tcuTexVerifierUtil
.wrap = function(mode
, c
, size
) {
247 // \note CL and GL modes are handled identically here, as verification process accounts for
248 // accuracy differences caused by different methods (wrapping vs. denormalizing first).
249 case tcuTexture
.WrapMode
.CLAMP_TO_EDGE
:
250 return deMath
.clamp(c
, 0, size
- 1);
252 case tcuTexture
.WrapMode
.REPEAT_GL
:
253 case tcuTexture
.WrapMode
.REPEAT_CL
:
254 return deMath
.imod(c
, size
);
256 case tcuTexture
.WrapMode
.MIRRORED_REPEAT_GL
:
257 case tcuTexture
.WrapMode
.MIRRORED_REPEAT_CL
:
258 return (size
- 1) - deMath
.mirror(deMath
.imod(c
, 2 * size
) - size
);
261 throw new Error('Wrap mode not supported.');