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.tcuTexCompareVerifier');
23 goog
.require('framework.common.tcuTexVerifierUtil');
24 goog
.require('framework.common.tcuTexture');
25 goog
.require('framework.common.tcuTextureUtil');
26 goog
.require('framework.delibs.debase.deMath');
28 goog
.scope(function() {
30 var tcuTexCompareVerifier
= framework
.common
.tcuTexCompareVerifier
;
31 var tcuTexture
= framework
.common
.tcuTexture
;
32 var deMath
= framework
.delibs
.debase
.deMath
;
33 var tcuTextureUtil
= framework
.common
.tcuTextureUtil
;
34 var tcuTexVerifierUtil
= framework
.common
.tcuTexVerifierUtil
;
37 * \brief Texture compare (shadow) lookup precision parameters.
40 * @param {Array<number>=} coordBits
41 * @param {Array<number>=} uvwBits
42 * @param {number=} pcfBits
43 * @param {number=} referenceBits
44 * @param {number=} resultBits
46 tcuTexCompareVerifier
.TexComparePrecision = function(coordBits
, uvwBits
, pcfBits
, referenceBits
, resultBits
) {
47 this.coordBits
= coordBits
=== undefined ? [22, 22, 22] : coordBits
;
48 this.uvwBits
= uvwBits
=== undefined ? [22, 22, 22] : uvwBits
;
49 this.pcfBits
= pcfBits
=== undefined ? 16 : pcfBits
;
50 this.referenceBits
= referenceBits
=== undefined ? 16 : referenceBits
;
51 this.resultBits
= resultBits
=== undefined ? 16 : resultBits
;
58 tcuTexCompareVerifier
.CmpResultSet = function() {
64 * @param {tcuTexture.CompareMode} compareMode
65 * @param {number} cmpValue_
66 * @param {number} cmpReference_
67 * @param {number} referenceBits
68 * @param {boolean} isFixedPoint
69 * @return {tcuTexCompareVerifier.CmpResultSet}
71 tcuTexCompareVerifier
.execCompare = function(compareMode
,
76 var clampValues
= isFixedPoint
; // if comparing against a floating point texture, ref (and value) is not clamped
77 var cmpValue
= (clampValues
) ? (deMath
.clamp(cmpValue_
, 0, 1)) : (cmpValue_
);
78 var cmpReference
= (clampValues
) ? (deMath
.clamp(cmpReference_
, 0, 1)) : (cmpReference_
);
79 var err
= tcuTexVerifierUtil
.computeFixedPointError(referenceBits
);
80 var res
= new tcuTexCompareVerifier
.CmpResultSet();
82 switch (compareMode
) {
83 case tcuTexture
.CompareMode
.COMPAREMODE_LESS
:
84 res
.isTrue
= cmpReference
- err
< cmpValue
;
85 res
.isFalse
= cmpReference
+ err
>= cmpValue
;
88 case tcuTexture
.CompareMode
.COMPAREMODE_LESS_OR_EQUAL
:
89 res
.isTrue
= cmpReference
- err
<= cmpValue
;
90 res
.isFalse
= cmpReference
+ err
> cmpValue
;
93 case tcuTexture
.CompareMode
.COMPAREMODE_GREATER
:
94 res
.isTrue
= cmpReference
+ err
> cmpValue
;
95 res
.isFalse
= cmpReference
- err
<= cmpValue
;
98 case tcuTexture
.CompareMode
.COMPAREMODE_GREATER_OR_EQUAL
:
99 res
.isTrue
= cmpReference
+ err
>= cmpValue
;
100 res
.isFalse
= cmpReference
- err
< cmpValue
;
103 case tcuTexture
.CompareMode
.COMPAREMODE_EQUAL
:
104 res
.isTrue
= deMath
.deInRange32(cmpValue
, cmpReference
- err
, cmpReference
+ err
);
105 res
.isFalse
= err
!= 0 || cmpValue
!= cmpReference
;
108 case tcuTexture
.CompareMode
.COMPAREMODE_NOT_EQUAL
:
109 res
.isTrue
= err
!= 0 || cmpValue
!= cmpReference
;
110 res
.isFalse
= deMath
.deInRange32(cmpValue
, cmpReference
- err
, cmpReference
+ err
);
113 case tcuTexture
.CompareMode
.COMPAREMODE_ALWAYS
:
117 case tcuTexture
.CompareMode
.COMPAREMODE_NEVER
:
122 throw new Error('Invalid compare mode:' + compareMode
);
125 assertMsgOptions(res
.isTrue
|| res
.isFalse
, 'Both tests failed!', false, true);
130 * @param {tcuTexture.TextureFormat} format
133 tcuTexCompareVerifier
.isFixedPointDepthTextureFormat = function(format
) {
134 var channelClass
= tcuTexture
.getTextureChannelClass(format
.type
);
136 if (format
.order
== tcuTexture
.ChannelOrder
.D
) {
137 // depth internal formats cannot be non-normalized integers
138 return channelClass
!= tcuTexture
.TextureChannelClass
.FLOATING_POINT
;
139 } else if (format
.order
== tcuTexture
.ChannelOrder
.DS
) {
140 // combined formats have no single channel class, detect format manually
141 switch (format
.type
) {
142 case tcuTexture
.ChannelType
.FLOAT_UNSIGNED_INT_24_8_REV
: return false;
143 case tcuTexture
.ChannelType
.UNSIGNED_INT_24_8
: return true;
146 throw new Error('Invalid texture format: ' + format
);
154 * @param {tcuTexture.CompareMode} compareMode
155 * @param {tcuTexCompareVerifier.TexComparePrecision} prec
156 * @param {Array<number>} depths
157 * @param {Array<number>} fBounds
158 * @param {number} cmpReference
159 * @param {number} result
160 * @param {boolean} isFixedPointDepth
163 tcuTexCompareVerifier
.isLinearCompareValid = function(compareMode
, prec
, depths
, fBounds
, cmpReference
, result
, isFixedPointDepth
) {
164 assertMsgOptions(fBounds
[0] >= 0 && fBounds
[0] <= fBounds
[1] && fBounds
[1] <= 1, 'Invalid fBounds', false, true);
169 var cmp0
= tcuTexCompareVerifier
.execCompare(compareMode
, d0
, cmpReference
, prec
.referenceBits
, isFixedPointDepth
);
170 var cmp1
= tcuTexCompareVerifier
.execCompare(compareMode
, d1
, cmpReference
, prec
.referenceBits
, isFixedPointDepth
);
171 var cmp
= [cmp0
, cmp1
];
173 var isTrue
= getMask(cmp
, function(x
) {return x
.isTrue
;});
174 var isFalse
= getMask(cmp
, function(x
) {return x
.isFalse
;});
179 var pcfErr
= tcuTexVerifierUtil
.computeFixedPointError(prec
.pcfBits
);
180 var resErr
= tcuTexVerifierUtil
.computeFixedPointError(prec
.resultBits
);
181 var totalErr
= pcfErr
+ resErr
;
183 for (var comb
= 0; comb
< 4; comb
++) {
184 if (((comb
& isTrue
) | (~comb
& isFalse
)) != 3)
187 var cmp0True
= ((comb
>> 0) & 1) != 0;
188 var cmp1True
= ((comb
>> 1) & 1) != 0;
190 var ref0
= cmp0True
? 1 : 0;
191 var ref1
= cmp1True
? 1 : 0;
193 var v0
= ref0
* (1 - f0
) + ref1
* f0
;
194 var v1
= ref0
* (1 - f1
) + ref1
* f1
;
195 var minV
= Math
.min(v0
, v1
);
196 var maxV
= Math
.max(v0
, v1
);
197 var minR
= minV
- totalErr
;
198 var maxR
= maxV
+ totalErr
;
200 if (deMath
.deInRange32(result
, minR
, maxR
))
207 * @param {number} val
208 * @param {number} offset
209 * @return {Array<boolean>}
211 tcuTexCompareVerifier
.extractBVec4 = function(val
, offset
) {
213 ((val
>> (offset
+ 0)) & 1) != 0,
214 ((val
>> (offset
+ 1)) & 1) != 0,
215 ((val
>> (offset
+ 2)) & 1) != 0,
216 ((val
>> (offset
+ 3)) & 1) != 0];
220 * Values are in order (0,0), (1,0), (0,1), (1,1)
221 * @param {Array<number>} values
226 tcuTexCompareVerifier
.bilinearInterpolate = function(values
, x
, y
) {
231 var res
= v00
* (1 - x
) * (1 - y
) + v10
* x
* (1 - y
) + v01
* (1 - x
) * y
+ v11
* x
* y
;
236 * @param {tcuTexture.CompareMode} compareMode
237 * @param {tcuTexCompareVerifier.TexComparePrecision} prec
238 * @param {Array<number>} depths vec4
239 * @param {number} cmpReference
240 * @param {number} result
241 * @param {boolean} isFixedPointDepth
244 tcuTexCompareVerifier
.isBilinearAnyCompareValid = function(compareMode
,
250 assertMsgOptions(prec
.pcfBits
=== 0, 'PCF bits must be 0', false, true);
257 var cmp0
= tcuTexCompareVerifier
.execCompare(compareMode
, d0
, cmpReference
, prec
.referenceBits
, isFixedPointDepth
);
258 var cmp1
= tcuTexCompareVerifier
.execCompare(compareMode
, d1
, cmpReference
, prec
.referenceBits
, isFixedPointDepth
);
259 var cmp2
= tcuTexCompareVerifier
.execCompare(compareMode
, d2
, cmpReference
, prec
.referenceBits
, isFixedPointDepth
);
260 var cmp3
= tcuTexCompareVerifier
.execCompare(compareMode
, d3
, cmpReference
, prec
.referenceBits
, isFixedPointDepth
);
262 var canBeTrue
= cmp0
.isTrue
|| cmp1
.isTrue
|| cmp2
.isTrue
|| cmp3
.isTrue
;
263 var canBeFalse
= cmp0
.isFalse
|| cmp1
.isFalse
|| cmp2
.isFalse
|| cmp3
.isFalse
;
265 var resErr
= tcuTexVerifierUtil
.computeFixedPointError(prec
.resultBits
);
267 var minBound
= canBeFalse
? 0 : 1;
268 var maxBound
= canBeTrue
? 1 : 0;
270 return deMath
.deInRange32(result
, minBound
- resErr
, maxBound
+ resErr
);
274 * @param {Array<tcuTexCompareVerifier.CmpResultSet>} arr
275 * @param {function(tcuTexCompareVerifier.CmpResultSet): boolean} getValue
278 var getMask = function(arr
, getValue
) {
280 for (var i
= 0; i
< arr
.length
; i
++) {
281 var val
= getValue(arr
[i
]);
289 * @param {tcuTexture.CompareMode} compareMode
290 * @param {tcuTexCompareVerifier.TexComparePrecision} prec
291 * @param {Array<number>} depths vec4
292 * @param {Array<number>} xBounds vec2
293 * @param {Array<number>} yBounds vec2
294 * @param {number} cmpReference
295 * @param {number} result
296 * @param {boolean} isFixedPointDepth
299 tcuTexCompareVerifier
.isBilinearPCFCompareValid = function(compareMode
,
307 assertMsgOptions(0.0 <= xBounds
[0] && xBounds
[0] <= xBounds
[1] && xBounds
[1] <= 1.0, 'x coordinate out of bounds', false, true);
308 assertMsgOptions(0.0 <= yBounds
[0] && yBounds
[0] <= yBounds
[1] && yBounds
[1] <= 1.0, 'y coordinate out of bounds', false, true);
309 assertMsgOptions(prec
.pcfBits
> 0, 'PCF bits must be > 0', false, true);
316 /** @type {Array<tcuTexCompareVerifier.CmpResultSet>} */ var cmp
= [];
317 cmp
[0] = tcuTexCompareVerifier
.execCompare(compareMode
, d0
, cmpReference
, prec
.referenceBits
, isFixedPointDepth
);
318 cmp
[1] = tcuTexCompareVerifier
.execCompare(compareMode
, d1
, cmpReference
, prec
.referenceBits
, isFixedPointDepth
);
319 cmp
[2] = tcuTexCompareVerifier
.execCompare(compareMode
, d2
, cmpReference
, prec
.referenceBits
, isFixedPointDepth
);
320 cmp
[3] = tcuTexCompareVerifier
.execCompare(compareMode
, d3
, cmpReference
, prec
.referenceBits
, isFixedPointDepth
);
322 var isTrue
= getMask(cmp
, function(x
) {return x
.isTrue
});
323 var isFalse
= getMask(cmp
, function(x
) {return x
.isFalse
});
325 // Interpolation parameters
332 var pcfErr
= tcuTexVerifierUtil
.computeFixedPointError(prec
.pcfBits
);
333 var resErr
= tcuTexVerifierUtil
.computeFixedPointError(prec
.resultBits
);
334 var totalErr
= pcfErr
+ resErr
;
336 // Iterate over all valid combinations.
337 // \note It is not enough to compute minmax over all possible result sets, as ranges may
338 // not necessarily overlap, i.e. there are gaps between valid ranges.
339 for (var comb
= 0; comb
< (1 << 4); comb
++) {
340 // Filter out invalid combinations:
341 // 1) True bit is set in comb but not in isTrue => sample can not be true
342 // 2) True bit is NOT set in comb and not in isFalse => sample can not be false
343 if (((comb
& isTrue
) | (~comb
& isFalse
)) != (1 << 4) - 1)
346 var cmpTrue
= tcuTexCompareVerifier
.extractBVec4(comb
, 0);
347 var refVal
= tcuTextureUtil
.select([1, 1, 1, 1], [0, 0, 0, 0], cmpTrue
);
349 var v0
= tcuTexCompareVerifier
.bilinearInterpolate(refVal
, x0
, y0
);
350 var v1
= tcuTexCompareVerifier
.bilinearInterpolate(refVal
, x1
, y0
);
351 var v2
= tcuTexCompareVerifier
.bilinearInterpolate(refVal
, x0
, y1
);
352 var v3
= tcuTexCompareVerifier
.bilinearInterpolate(refVal
, x1
, y1
);
353 var minV
= Math
.min(v0
, v1
, v2
, v3
);
354 var maxV
= Math
.max(v0
, v1
, v2
, v3
);
355 var minR
= minV
- totalErr
;
356 var maxR
= maxV
+ totalErr
;
358 if (deMath
.deInRange32(result
, minR
, maxR
))
366 * @param {tcuTexture.CompareMode} compareMode
367 * @param {tcuTexCompareVerifier.TexComparePrecision} prec
368 * @param {Array<number>} depths vec4
369 * @param {Array<number>} xBounds vec2
370 * @param {Array<number>} yBounds vec2
371 * @param {number} cmpReference
372 * @param {number} result
373 * @param {boolean} isFixedPointDepth
376 tcuTexCompareVerifier
.isBilinearCompareValid = function(compareMode
,
384 if (prec
.pcfBits
> 0)
385 return tcuTexCompareVerifier
.isBilinearPCFCompareValid(compareMode
, prec
, depths
, xBounds
, yBounds
, cmpReference
, result
, isFixedPointDepth
);
387 return tcuTexCompareVerifier
.isBilinearAnyCompareValid(compareMode
, prec
, depths
, cmpReference
, result
, isFixedPointDepth
);
390 * @param {tcuTexture.ConstPixelBufferAccess} level
391 * @param {tcuTexture.Sampler} sampler
392 * @param {tcuTexCompareVerifier.TexComparePrecision} prec
393 * @param {Array<number>} coord vec2 texture coordinates
394 * @param {number} coordZ
395 * @param {number} cmpReference
396 * @param {number} result
399 tcuTexCompareVerifier
.isLinearCompareResultValid = function(level
,
406 var isFixedPointDepth
= tcuTexCompareVerifier
.isFixedPointDepthTextureFormat(level
.getFormat());
407 var uBounds
= tcuTexVerifierUtil
.computeNonNormalizedCoordBounds(sampler
.normalizedCoords
, level
.getWidth(), coord
[0], prec
.coordBits
[0], prec
.uvwBits
[0]);
408 var vBounds
= tcuTexVerifierUtil
.computeNonNormalizedCoordBounds(sampler
.normalizedCoords
, level
.getHeight(), coord
[1], prec
.coordBits
[1], prec
.uvwBits
[1]);
410 // Integer coordinate bounds for (x0,y0) - without wrap mode
411 var minI
= Math
.floor(uBounds
[0] - 0.5);
412 var maxI
= Math
.floor(uBounds
[1] - 0.5);
413 var minJ
= Math
.floor(vBounds
[0] - 0.5);
414 var maxJ
= Math
.floor(vBounds
[1] - 0.5);
416 var w
= level
.getWidth();
417 var h
= level
.getHeight();
419 // \todo [2013-07-03 pyry] This could be optimized by first computing ranges based on wrap mode.
421 for (var j
= minJ
; j
<= maxJ
; j
++) {
422 for (var i
= minI
; i
<= maxI
; i
++) {
423 // Wrapped coordinates
424 var x0
= tcuTexVerifierUtil
.wrap(sampler
.wrapS
, i
, w
);
425 var x1
= tcuTexVerifierUtil
.wrap(sampler
.wrapS
, i
+ 1, w
);
426 var y0
= tcuTexVerifierUtil
.wrap(sampler
.wrapT
, j
, h
);
427 var y1
= tcuTexVerifierUtil
.wrap(sampler
.wrapT
, j
+ 1, h
);
429 // Bounds for filtering factors
430 var minA
= deMath
.clamp((uBounds
[0] - 0.5) - i
, 0, 1);
431 var maxA
= deMath
.clamp((uBounds
[1] - 0.5) - i
, 0, 1);
432 var minB
= deMath
.clamp((vBounds
[0] - 0.5) - j
, 0, 1);
433 var maxB
= deMath
.clamp((vBounds
[1] - 0.5) - j
, 0, 1);
436 level
.getPixDepth(x0
, y0
, coordZ
),
437 level
.getPixDepth(x1
, y0
, coordZ
),
438 level
.getPixDepth(x0
, y1
, coordZ
),
439 level
.getPixDepth(x1
, y1
, coordZ
)
442 if (tcuTexCompareVerifier
.isBilinearCompareValid(sampler
.compare
, prec
, depths
, [minA
, maxA
], [minB
, maxB
], cmpReference
, result
, isFixedPointDepth
))
451 * @param {tcuTexCompareVerifier.CmpResultSet} resultSet
452 * @param {number} result
453 * @param {number} resultBits
455 tcuTexCompareVerifier
.isResultInSet = function(resultSet
, result
, resultBits
) {
456 var err
= tcuTexVerifierUtil
.computeFixedPointError(resultBits
);
457 var minR
= result
- err
;
458 var maxR
= result
+ err
;
460 return (resultSet
.isTrue
&& deMath
.deInRange32(1, minR
, maxR
)) ||
461 (resultSet
.isFalse
&& deMath
.deInRange32(0, minR
, maxR
));
465 * @param {tcuTexture.ConstPixelBufferAccess} level
466 * @param {tcuTexture.Sampler} sampler
467 * @param {tcuTexCompareVerifier.TexComparePrecision} prec
468 * @param {Array<number>} coord vec2 texture coordinates
469 * @param {number} coordZ
470 * @param {number} cmpReference
471 * @param {number} result
474 tcuTexCompareVerifier
.isNearestCompareResultValid = function(level
,
481 var isFixedPointDepth
= tcuTexCompareVerifier
.isFixedPointDepthTextureFormat(level
.getFormat());
482 var uBounds
= tcuTexVerifierUtil
.computeNonNormalizedCoordBounds(sampler
.normalizedCoords
, level
.getWidth(), coord
[0], prec
.coordBits
[0], prec
.uvwBits
[0]);
483 var vBounds
= tcuTexVerifierUtil
.computeNonNormalizedCoordBounds(sampler
.normalizedCoords
, level
.getHeight(), coord
[1], prec
.coordBits
[1], prec
.uvwBits
[1]);
485 // Integer coordinates - without wrap mode
486 var minI
= Math
.floor(uBounds
[0]);
487 var maxI
= Math
.floor(uBounds
[1]);
488 var minJ
= Math
.floor(vBounds
[0]);
489 var maxJ
= Math
.floor(vBounds
[1]);
491 for (var j
= minJ
; j
<= maxJ
; j
++) {
492 for (var i
= minI
; i
<= maxI
; i
++) {
493 var x
= tcuTexVerifierUtil
.wrap(sampler
.wrapS
, i
, level
.getWidth());
494 var y
= tcuTexVerifierUtil
.wrap(sampler
.wrapT
, j
, level
.getHeight());
495 var depth
= level
.getPixDepth(x
, y
, coordZ
);
496 var resSet
= tcuTexCompareVerifier
.execCompare(sampler
.compare
, depth
, cmpReference
, prec
.referenceBits
, isFixedPointDepth
);
498 if (tcuTexCompareVerifier
.isResultInSet(resSet
, result
, prec
.resultBits
))
507 * @param {tcuTexture.ConstPixelBufferAccess} level
508 * @param {tcuTexture.Sampler} sampler
509 * @param {tcuTexture.FilterMode} filterMode
510 * @param {tcuTexCompareVerifier.TexComparePrecision} prec
511 * @param {Array<number>} coord vec2 texture coordinates
512 * @param {number} coordZ
513 * @param {number} cmpReference
514 * @param {number} result
517 tcuTexCompareVerifier
.isLevelCompareResultValid = function(level
,
525 if (filterMode
== tcuTexture
.FilterMode
.LINEAR
)
526 return tcuTexCompareVerifier
.isLinearCompareResultValid(level
, sampler
, prec
, coord
, coordZ
, cmpReference
, result
);
528 return tcuTexCompareVerifier
.isNearestCompareResultValid(level
, sampler
, prec
, coord
, coordZ
, cmpReference
, result
);
532 * @param {tcuTexture.CompareMode} compareMode
533 * @param {tcuTexCompareVerifier.TexComparePrecision} prec
534 * @param {Array<number>} depths0 vec4
535 * @param {Array<number>} depths1 vec4
536 * @param {number} cmpReference
537 * @param {number} result
538 * @param {boolean} isFixedPointDepth
541 tcuTexCompareVerifier
.isTrilinearAnyCompareValid = function(compareMode
,
548 assertMsgOptions(prec
.pcfBits
=== 0, 'PCF bits must be 0', false, true);
550 var cmp00
= tcuTexCompareVerifier
.execCompare(compareMode
, depths0
[0], cmpReference
, prec
.referenceBits
, isFixedPointDepth
);
551 var cmp01
= tcuTexCompareVerifier
.execCompare(compareMode
, depths0
[1], cmpReference
, prec
.referenceBits
, isFixedPointDepth
);
552 var cmp02
= tcuTexCompareVerifier
.execCompare(compareMode
, depths0
[2], cmpReference
, prec
.referenceBits
, isFixedPointDepth
);
553 var cmp03
= tcuTexCompareVerifier
.execCompare(compareMode
, depths0
[3], cmpReference
, prec
.referenceBits
, isFixedPointDepth
);
554 var cmp10
= tcuTexCompareVerifier
.execCompare(compareMode
, depths1
[0], cmpReference
, prec
.referenceBits
, isFixedPointDepth
);
555 var cmp11
= tcuTexCompareVerifier
.execCompare(compareMode
, depths1
[1], cmpReference
, prec
.referenceBits
, isFixedPointDepth
);
556 var cmp12
= tcuTexCompareVerifier
.execCompare(compareMode
, depths1
[2], cmpReference
, prec
.referenceBits
, isFixedPointDepth
);
557 var cmp13
= tcuTexCompareVerifier
.execCompare(compareMode
, depths1
[3], cmpReference
, prec
.referenceBits
, isFixedPointDepth
);
559 var canBeTrue
= cmp00
.isTrue
||
567 var canBeFalse
= cmp00
.isFalse
||
576 var resErr
= tcuTexVerifierUtil
.computeFixedPointError(prec
.resultBits
);
578 var minBound
= canBeFalse
? 0 : 1;
579 var maxBound
= canBeTrue
? 1 : 0;
581 return deMath
.deInRange32(result
, minBound
- resErr
, maxBound
+ resErr
);
585 * @param {tcuTexture.CompareMode} compareMode
586 * @param {tcuTexCompareVerifier.TexComparePrecision} prec
587 * @param {Array<number>} depths0 vec4
588 * @param {Array<number>} depths1 vec4
589 * @param {Array<number>} xBounds0
590 * @param {Array<number>} yBounds0
591 * @param {Array<number>} xBounds1
592 * @param {Array<number>} yBounds1
593 * @param {Array<number>} fBounds
594 * @param {number} cmpReference
595 * @param {number} result
596 * @param {boolean} isFixedPointDepth
599 tcuTexCompareVerifier
.isTrilinearPCFCompareValid = function(compareMode
,
611 assertMsgOptions(0.0 <= xBounds0
[0] && xBounds0
[0] <= xBounds0
[1] && xBounds0
[1] <= 1.0, 'x0 coordinate out of bounds', false, true);
612 assertMsgOptions(0.0 <= yBounds0
[0] && yBounds0
[0] <= yBounds0
[1] && yBounds0
[1] <= 1.0, 'y0 coordinate out of bounds', false, true);
613 assertMsgOptions(0.0 <= xBounds1
[0] && xBounds1
[0] <= xBounds1
[1] && xBounds1
[1] <= 1.0, 'x1 coordinate out of bounds', false, true);
614 assertMsgOptions(0.0 <= yBounds1
[0] && yBounds1
[0] <= yBounds1
[1] && yBounds1
[1] <= 1.0, 'y1 coordinate out of bounds', false, true);
615 assertMsgOptions(0.0 <= fBounds
[0] && fBounds
[0] <= fBounds
[1] && fBounds
[1] <= 1.0, 'linear factor out of bounds', false, true);
616 assertMsgOptions(prec
.pcfBits
> 0, 'PCF bits must be > 0', false, true);
618 /** @type {Array<tcuTexCompareVerifier.CmpResultSet>} */ var cmp
= [];
619 cmp
.push(tcuTexCompareVerifier
.execCompare(compareMode
, depths0
[0], cmpReference
, prec
.referenceBits
, isFixedPointDepth
));
620 cmp
.push(tcuTexCompareVerifier
.execCompare(compareMode
, depths0
[1], cmpReference
, prec
.referenceBits
, isFixedPointDepth
));
621 cmp
.push(tcuTexCompareVerifier
.execCompare(compareMode
, depths0
[2], cmpReference
, prec
.referenceBits
, isFixedPointDepth
));
622 cmp
.push(tcuTexCompareVerifier
.execCompare(compareMode
, depths0
[3], cmpReference
, prec
.referenceBits
, isFixedPointDepth
));
623 cmp
.push(tcuTexCompareVerifier
.execCompare(compareMode
, depths1
[0], cmpReference
, prec
.referenceBits
, isFixedPointDepth
));
624 cmp
.push(tcuTexCompareVerifier
.execCompare(compareMode
, depths1
[1], cmpReference
, prec
.referenceBits
, isFixedPointDepth
));
625 cmp
.push(tcuTexCompareVerifier
.execCompare(compareMode
, depths1
[2], cmpReference
, prec
.referenceBits
, isFixedPointDepth
));
626 cmp
.push(tcuTexCompareVerifier
.execCompare(compareMode
, depths1
[3], cmpReference
, prec
.referenceBits
, isFixedPointDepth
));
628 var isTrue
= getMask(cmp
, function(x
) {return x
.isTrue
});
629 var isFalse
= getMask(cmp
, function(x
) {return x
.isFalse
});
632 var pcfErr
= tcuTexVerifierUtil
.computeFixedPointError(prec
.pcfBits
);
633 var resErr
= tcuTexVerifierUtil
.computeFixedPointError(prec
.resultBits
);
634 var totalErr
= pcfErr
+ resErr
;
636 // Iterate over all valid combinations.
637 for (var comb
= 0; comb
< (1 << 8); comb
++) {
638 // Filter out invalid combinations.
639 if (((comb
& isTrue
) | (~comb
& isFalse
)) != (1 << 8) - 1)
642 var cmpTrue0
= tcuTexCompareVerifier
.extractBVec4(comb
, 0);
643 var cmpTrue1
= tcuTexCompareVerifier
.extractBVec4(comb
, 4);
644 var refVal0
= tcuTextureUtil
.select([1, 1, 1, 1], [0, 0, 0, 0], cmpTrue0
);
645 var refVal1
= tcuTextureUtil
.select([1, 1, 1, 1], [0, 0, 0, 0], cmpTrue1
);
647 // Bilinear interpolation within levels.
648 var v00
= tcuTexCompareVerifier
.bilinearInterpolate(refVal0
, xBounds0
[0], yBounds0
[0]);
649 var v01
= tcuTexCompareVerifier
.bilinearInterpolate(refVal0
, xBounds0
[1], yBounds0
[0]);
650 var v02
= tcuTexCompareVerifier
.bilinearInterpolate(refVal0
, xBounds0
[0], yBounds0
[1]);
651 var v03
= tcuTexCompareVerifier
.bilinearInterpolate(refVal0
, xBounds0
[1], yBounds0
[1]);
652 var minV0
= Math
.min(v00
, v01
, v02
, v03
);
653 var maxV0
= Math
.max(v00
, v01
, v02
, v03
);
655 var v10
= tcuTexCompareVerifier
.bilinearInterpolate(refVal1
, xBounds1
[0], yBounds1
[0]);
656 var v11
= tcuTexCompareVerifier
.bilinearInterpolate(refVal1
, xBounds1
[1], yBounds1
[0]);
657 var v12
= tcuTexCompareVerifier
.bilinearInterpolate(refVal1
, xBounds1
[0], yBounds1
[1]);
658 var v13
= tcuTexCompareVerifier
.bilinearInterpolate(refVal1
, xBounds1
[1], yBounds1
[1]);
659 var minV1
= Math
.min(v10
, v11
, v12
, v13
);
660 var maxV1
= Math
.max(v10
, v11
, v12
, v13
);
662 // Compute min-max bounds by filtering between minimum bounds and maximum bounds between levels.
663 // HW can end up choosing pretty much any of samples between levels, and thus interpolating
664 // between minimums should yield lower bound for range, and same for upper bound.
665 // \todo [2013-07-17 pyry] This seems separable? Can this be optimized? At least ranges could be pre-computed and later combined.
666 var minF0
= minV0
* (1 - fBounds
[0]) + minV1
* fBounds
[0];
667 var minF1
= minV0
* (1 - fBounds
[1]) + minV1
* fBounds
[1];
668 var maxF0
= maxV0
* (1 - fBounds
[0]) + maxV1
* fBounds
[0];
669 var maxF1
= maxV0
* (1 - fBounds
[1]) + maxV1
* fBounds
[1];
671 var minF
= Math
.min(minF0
, minF1
);
672 var maxF
= Math
.max(maxF0
, maxF1
);
674 var minR
= minF
- totalErr
;
675 var maxR
= maxF
+ totalErr
;
677 if (deMath
.deInRange32(result
, minR
, maxR
))
686 * @param {tcuTexture.CompareMode} compareMode
687 * @param {tcuTexCompareVerifier.TexComparePrecision} prec
688 * @param {Array<number>} depths0 vec4
689 * @param {Array<number>} depths1 vec4
690 * @param {Array<number>} xBounds0
691 * @param {Array<number>} yBounds0
692 * @param {Array<number>} xBounds1
693 * @param {Array<number>} yBounds1
694 * @param {Array<number>} fBounds
695 * @param {number} cmpReference
696 * @param {number} result
697 * @param {boolean} isFixedPointDepth
700 tcuTexCompareVerifier
.isTrilinearCompareValid = function(compareMode
,
712 if (prec
.pcfBits
> 0)
713 return tcuTexCompareVerifier
.isTrilinearPCFCompareValid(compareMode
, prec
, depths0
, depths1
, xBounds0
, yBounds0
, xBounds1
, yBounds1
, fBounds
, cmpReference
, result
, isFixedPointDepth
);
715 return tcuTexCompareVerifier
.isTrilinearAnyCompareValid(compareMode
, prec
, depths0
, depths1
, cmpReference
, result
, isFixedPointDepth
);
719 * @param {tcuTexture.ConstPixelBufferAccess} level0
720 * @param {tcuTexture.ConstPixelBufferAccess} level1
721 * @param {tcuTexture.Sampler} sampler
722 * @param {tcuTexCompareVerifier.TexComparePrecision} prec
723 * @param {Array<number>} coord vec2 texture coordinates
724 * @param {number} coordZ
725 * @param {Array<number>} fBounds vec2
726 * @param {number} cmpReference
727 * @param {number} result
730 tcuTexCompareVerifier
.isLinearMipmapLinearCompareResultValid = function(level0
,
739 var isFixedPointDepth
= tcuTexCompareVerifier
.isFixedPointDepthTextureFormat(level0
.getFormat());
741 // \todo [2013-07-04 pyry] This is strictly not correct as coordinates between levels should be dependent.
742 // Right now this allows pairing any two valid bilinear quads.
744 var w0
= level0
.getWidth();
745 var w1
= level1
.getWidth();
746 var h0
= level0
.getHeight();
747 var h1
= level1
.getHeight();
749 var uBounds0
= tcuTexVerifierUtil
.computeNonNormalizedCoordBounds(sampler
.normalizedCoords
, w0
, coord
[0], prec
.coordBits
[0], prec
.uvwBits
[0]);
750 var uBounds1
= tcuTexVerifierUtil
.computeNonNormalizedCoordBounds(sampler
.normalizedCoords
, w1
, coord
[0], prec
.coordBits
[0], prec
.uvwBits
[0]);
751 var vBounds0
= tcuTexVerifierUtil
.computeNonNormalizedCoordBounds(sampler
.normalizedCoords
, h0
, coord
[1], prec
.coordBits
[1], prec
.uvwBits
[1]);
752 var vBounds1
= tcuTexVerifierUtil
.computeNonNormalizedCoordBounds(sampler
.normalizedCoords
, h1
, coord
[1], prec
.coordBits
[1], prec
.uvwBits
[1]);
754 // Integer coordinates - without wrap mode
755 var minI0
= Math
.floor(uBounds0
[0] - 0.5);
756 var maxI0
= Math
.floor(uBounds0
[1] - 0.5);
757 var minI1
= Math
.floor(uBounds1
[0] - 0.5);
758 var maxI1
= Math
.floor(uBounds1
[1] - 0.5);
759 var minJ0
= Math
.floor(vBounds0
[0] - 0.5);
760 var maxJ0
= Math
.floor(vBounds0
[1] - 0.5);
761 var minJ1
= Math
.floor(vBounds1
[0] - 0.5);
762 var maxJ1
= Math
.floor(vBounds1
[1] - 0.5);
764 for (var j0
= minJ0
; j0
<= maxJ0
; j0
++) {
765 for (var i0
= minI0
; i0
<= maxI0
; i0
++) {
766 var minA0
= deMath
.clamp((uBounds0
[0] - 0.5) - i0
, 0, 1);
767 var maxA0
= deMath
.clamp((uBounds0
[1] - 0.5) - i0
, 0, 1);
768 var minB0
= deMath
.clamp((vBounds0
[0] - 0.5) - j0
, 0, 1);
769 var maxB0
= deMath
.clamp((vBounds0
[1] - 0.5) - j0
, 0, 1);
772 var x0
= tcuTexVerifierUtil
.wrap(sampler
.wrapS
, i0
, w0
);
773 var x1
= tcuTexVerifierUtil
.wrap(sampler
.wrapS
, i0
+ 1, w0
);
774 var y0
= tcuTexVerifierUtil
.wrap(sampler
.wrapT
, j0
, h0
);
775 var y1
= tcuTexVerifierUtil
.wrap(sampler
.wrapT
, j0
+ 1, h0
);
777 depths0
[0] = level0
.getPixDepth(x0
, y0
, coordZ
);
778 depths0
[1] = level0
.getPixDepth(x1
, y0
, coordZ
);
779 depths0
[2] = level0
.getPixDepth(x0
, y1
, coordZ
);
780 depths0
[3] = level0
.getPixDepth(x1
, y1
, coordZ
);
782 for (var j1
= minJ1
; j1
<= maxJ1
; j1
++) {
783 for (var i1
= minI1
; i1
<= maxI1
; i1
++) {
784 var minA1
= deMath
.clamp((uBounds1
[0] - 0.5) - i1
, 0, 1);
785 var maxA1
= deMath
.clamp((uBounds1
[1] - 0.5) - i1
, 0, 1);
786 var minB1
= deMath
.clamp((vBounds1
[0] - 0.5) - j1
, 0, 1);
787 var maxB1
= deMath
.clamp((vBounds1
[1] - 0.5) - j1
, 0, 1);
790 x0
= tcuTexVerifierUtil
.wrap(sampler
.wrapS
, i1
, w1
);
791 x1
= tcuTexVerifierUtil
.wrap(sampler
.wrapS
, i1
+ 1, w1
);
792 y0
= tcuTexVerifierUtil
.wrap(sampler
.wrapT
, j1
, h1
);
793 y1
= tcuTexVerifierUtil
.wrap(sampler
.wrapT
, j1
+ 1, h1
);
795 depths1
[0] = level1
.getPixDepth(x0
, y0
, coordZ
);
796 depths1
[1] = level1
.getPixDepth(x1
, y0
, coordZ
);
797 depths1
[2] = level1
.getPixDepth(x0
, y1
, coordZ
);
798 depths1
[3] = level1
.getPixDepth(x1
, y1
, coordZ
);
800 if (tcuTexCompareVerifier
.isTrilinearCompareValid(sampler
.compare
, prec
, depths0
, depths1
,
801 [minA0
, maxA0
], [minB0
, maxB0
],
802 [minA1
, maxA1
], [minB1
, maxB1
],
803 fBounds
, cmpReference
, result
, isFixedPointDepth
))
814 * @param {tcuTexture.ConstPixelBufferAccess} level0
815 * @param {tcuTexture.ConstPixelBufferAccess} level1
816 * @param {tcuTexture.Sampler} sampler
817 * @param {tcuTexCompareVerifier.TexComparePrecision} prec
818 * @param {Array<number>} coord vec2 texture coordinates
819 * @param {number} coordZ
820 * @param {Array<number>} fBounds vec2
821 * @param {number} cmpReference
822 * @param {number} result
825 tcuTexCompareVerifier
.isNearestMipmapLinearCompareResultValid = function(level0
,
834 var isFixedPointDepth
= tcuTexCompareVerifier
.isFixedPointDepthTextureFormat(level0
.getFormat());
836 var w0
= level0
.getWidth();
837 var w1
= level1
.getWidth();
838 var h0
= level0
.getHeight();
839 var h1
= level1
.getHeight();
841 var uBounds0
= tcuTexVerifierUtil
.computeNonNormalizedCoordBounds(sampler
.normalizedCoords
, w0
, coord
[0], prec
.coordBits
[0], prec
.uvwBits
[0]);
842 var uBounds1
= tcuTexVerifierUtil
.computeNonNormalizedCoordBounds(sampler
.normalizedCoords
, w1
, coord
[0], prec
.coordBits
[0], prec
.uvwBits
[0]);
843 var vBounds0
= tcuTexVerifierUtil
.computeNonNormalizedCoordBounds(sampler
.normalizedCoords
, h0
, coord
[1], prec
.coordBits
[1], prec
.uvwBits
[1]);
844 var vBounds1
= tcuTexVerifierUtil
.computeNonNormalizedCoordBounds(sampler
.normalizedCoords
, h1
, coord
[1], prec
.coordBits
[1], prec
.uvwBits
[1]);
846 var minI0
= Math
.floor(uBounds0
[0]);
847 var maxI0
= Math
.floor(uBounds0
[1]);
848 var minI1
= Math
.floor(uBounds1
[0]);
849 var maxI1
= Math
.floor(uBounds1
[1]);
850 var minJ0
= Math
.floor(vBounds0
[0]);
851 var maxJ0
= Math
.floor(vBounds0
[1]);
852 var minJ1
= Math
.floor(vBounds1
[0]);
853 var maxJ1
= Math
.floor(vBounds1
[1]);
855 for (var j0
= minJ0
; j0
<= maxJ0
; j0
++) {
856 for (var i0
= minI0
; i0
<= maxI0
; i0
++) {
857 var x0
= tcuTexVerifierUtil
.wrap(sampler
.wrapS
, i0
, w0
);
858 var y0
= tcuTexVerifierUtil
.wrap(sampler
.wrapT
, j0
, h0
);
860 // Derivated from C++ dEQP function lookupDepth()
861 // Since x0 and y0 are wrapped, here lookupDepth() returns the same result as getPixDepth()
862 assertMsgOptions(deMath
.deInBounds32(x0
, 0, level0
.getWidth()) && deMath
.deInBounds32(y0
, 0, level0
.getHeight()) && deMath
.deInBounds32(coordZ
, 0, level0
.getDepth()), 'x0, y0 or coordZ out of bound.', false, true);
863 var depth0
= level0
.getPixDepth(x0
, y0
, coordZ
);
865 for (var j1
= minJ1
; j1
<= maxJ1
; j1
++) {
866 for (var i1
= minI1
; i1
<= maxI1
; i1
++) {
867 var x1
= tcuTexVerifierUtil
.wrap(sampler
.wrapS
, i1
, w1
);
868 var y1
= tcuTexVerifierUtil
.wrap(sampler
.wrapT
, j1
, h1
);
870 // Derivated from C++ dEQP function lookupDepth()
871 // Since x1 and y1 are wrapped, here lookupDepth() returns the same result as getPixDepth()
872 assertMsgOptions(deMath
.deInBounds32(x1
, 0, level1
.getWidth()) && deMath
.deInBounds32(y1
, 0, level1
.getHeight()), 'x1 or y1 out of bound.', false, true);
873 var depth1
= level1
.getPixDepth(x1
, y1
, coordZ
);
875 if (tcuTexCompareVerifier
.isLinearCompareValid(sampler
.compare
, prec
, [depth0
, depth1
], fBounds
, cmpReference
, result
, isFixedPointDepth
))
886 * @param {tcuTexture.ConstPixelBufferAccess} level0
887 * @param {tcuTexture.ConstPixelBufferAccess} level1
888 * @param {tcuTexture.Sampler} sampler
889 * @param {tcuTexture.FilterMode} levelFilter
890 * @param {tcuTexCompareVerifier.TexComparePrecision} prec
891 * @param {Array<number>} coord vec2 texture coordinates
892 * @param {number} coordZ
893 * @param {Array<number>} fBounds vec2
894 * @param {number} cmpReference
895 * @param {number} result
898 tcuTexCompareVerifier
.isMipmapLinearCompareResultValid = function(level0
,
908 if (levelFilter
== tcuTexture
.FilterMode
.LINEAR
)
909 return tcuTexCompareVerifier
.isLinearMipmapLinearCompareResultValid(level0
, level1
, sampler
, prec
, coord
, coordZ
, fBounds
, cmpReference
, result
);
911 return tcuTexCompareVerifier
.isNearestMipmapLinearCompareResultValid(level0
, level1
, sampler
, prec
, coord
, coordZ
, fBounds
, cmpReference
, result
);
915 * @param {tcuTexture.Texture2DView} texture
916 * @param {tcuTexture.Sampler} sampler
917 * @param {tcuTexCompareVerifier.TexComparePrecision} prec
918 * @param {Array<number>} coord vec2 texture coordinates
919 * @param {Array<number>} lodBounds vec2 level-of-detail bounds
920 * @param {number} cmpReference
921 * @param {number} result
924 tcuTexCompareVerifier
.isTexCompareResultValid2D = function(texture
, sampler
, prec
, coord
, lodBounds
, cmpReference
, result
) {
925 var minLod
= lodBounds
[0];
926 var maxLod
= lodBounds
[1];
927 var canBeMagnified
= minLod
<= sampler
.lodThreshold
;
928 var canBeMinified
= maxLod
> sampler
.lodThreshold
;
930 if (canBeMagnified
) {
931 if (tcuTexCompareVerifier
.isLevelCompareResultValid(texture
.getLevel(0), sampler
, sampler
.magFilter
, prec
, coord
, 0, cmpReference
, result
))
936 var isNearestMipmap
= tcuTexVerifierUtil
.isNearestMipmapFilter(sampler
.minFilter
);
937 var isLinearMipmap
= tcuTexVerifierUtil
.isLinearMipmapFilter(sampler
.minFilter
);
939 var maxTexLevel
= texture
.getNumLevels() - 1;
941 assertMsgOptions(minTexLevel
< maxTexLevel
, 'Invalid texture levels.', false, true);
943 if (isLinearMipmap
) {
944 var minLevel
= deMath
.clamp(Math
.floor(minLod
), minTexLevel
, maxTexLevel
- 1);
945 var maxLevel
= deMath
.clamp(Math
.floor(maxLod
), minTexLevel
, maxTexLevel
- 1);
947 assertMsgOptions(minLevel
<= maxLevel
, 'Invalid texture levels.', false, true);
949 for (var level
= minLevel
; level
<= maxLevel
; level
++) {
950 var minF
= deMath
.clamp(minLod
- level
, 0, 1);
951 var maxF
= deMath
.clamp(maxLod
- level
, 0, 1);
953 if (tcuTexCompareVerifier
.isMipmapLinearCompareResultValid(texture
.getLevel(level
), texture
.getLevel(level
+ 1), sampler
, tcuTexVerifierUtil
.getLevelFilter(sampler
.minFilter
), prec
, coord
, 0, [minF
, maxF
], cmpReference
, result
))
956 } else if (isNearestMipmap
) {
957 // \note The accurate formula for nearest mipmapping is level = ceil(lod + 0.5) - 1 but Khronos has made
958 // decision to allow floor(lod + 0.5) as well.
959 var minLevel
= deMath
.clamp(Math
.ceil(minLod
+ 0.5) - 1, minTexLevel
, maxTexLevel
);
960 var maxLevel
= deMath
.clamp(Math
.floor(maxLod
+ 0.5), minTexLevel
, maxTexLevel
);
962 assertMsgOptions(minLevel
<= maxLevel
, 'Invalid texture levels.', false, true);
964 for (var level
= minLevel
; level
<= maxLevel
; level
++) {
965 if (tcuTexCompareVerifier
.isLevelCompareResultValid(texture
.getLevel(level
), sampler
, tcuTexVerifierUtil
.getLevelFilter(sampler
.minFilter
), prec
, coord
, 0, cmpReference
, result
))
969 if (tcuTexCompareVerifier
.isLevelCompareResultValid(texture
.getLevel(0), sampler
, sampler
.minFilter
, prec
, coord
, 0, cmpReference
, result
))
978 * @param {tcuTexture.TextureCubeView} texture
979 * @param {number} baseLevelNdx
980 * @param {tcuTexture.Sampler} sampler
981 * @param {tcuTexCompareVerifier.TexComparePrecision} prec
982 * @param {tcuTexture.CubeFaceCoords} coords
983 * @param {Array<number>} fBounds vec2
984 * @param {number} cmpReference
985 * @param {number} result
988 tcuTexCompareVerifier
.isSeamplessLinearMipmapLinearCompareResultValid = function(texture
,
996 var isFixedPointDepth
= tcuTexCompareVerifier
.isFixedPointDepthTextureFormat(texture
.getLevelFace(baseLevelNdx
, tcuTexture
.CubeFace
.CUBEFACE_NEGATIVE_X
).getFormat());
997 var size0
= texture
.getLevelFace(baseLevelNdx
, coords
.face
).getWidth();
998 var size1
= texture
.getLevelFace(baseLevelNdx
+ 1, coords
.face
).getWidth();
1000 var uBounds0
= tcuTexVerifierUtil
.computeNonNormalizedCoordBounds(sampler
.normalizedCoords
, size0
, coords
.s
, prec
.coordBits
[0], prec
.uvwBits
[0]);
1001 var uBounds1
= tcuTexVerifierUtil
.computeNonNormalizedCoordBounds(sampler
.normalizedCoords
, size1
, coords
.s
, prec
.coordBits
[0], prec
.uvwBits
[0]);
1002 var vBounds0
= tcuTexVerifierUtil
.computeNonNormalizedCoordBounds(sampler
.normalizedCoords
, size0
, coords
.t
, prec
.coordBits
[1], prec
.uvwBits
[1]);
1003 var vBounds1
= tcuTexVerifierUtil
.computeNonNormalizedCoordBounds(sampler
.normalizedCoords
, size1
, coords
.t
, prec
.coordBits
[1], prec
.uvwBits
[1]);
1005 // Integer coordinates - without wrap mode
1006 var minI0
= Math
.floor(uBounds0
[0] - 0.5);
1007 var maxI0
= Math
.floor(uBounds0
[1] - 0.5);
1008 var minI1
= Math
.floor(uBounds1
[0] - 0.5);
1009 var maxI1
= Math
.floor(uBounds1
[1] - 0.5);
1010 var minJ0
= Math
.floor(vBounds0
[0] - 0.5);
1011 var maxJ0
= Math
.floor(vBounds0
[1] - 0.5);
1012 var minJ1
= Math
.floor(vBounds1
[0] - 0.5);
1013 var maxJ1
= Math
.floor(vBounds1
[1] - 0.5);
1015 /** @type {Array<tcuTexture.ConstPixelBufferAccess>} */ var faces0
= [];
1016 /** @type {Array<tcuTexture.ConstPixelBufferAccess>} */ var faces1
= [];
1018 for (var key
in tcuTexture
.CubeFace
) {
1019 var face
= tcuTexture
.CubeFace
[key
];
1020 faces0
[face
] = texture
.getLevelFace(baseLevelNdx
, face
);
1021 faces1
[face
] = texture
.getLevelFace(baseLevelNdx
+ 1, face
);
1024 for (var j0
= minJ0
; j0
<= maxJ0
; j0
++) {
1025 for (var i0
= minI0
; i0
<= maxI0
; i0
++) {
1026 var minA0
= deMath
.clamp((uBounds0
[0] - 0.5) - i0
, 0, 1);
1027 var maxA0
= deMath
.clamp((uBounds0
[1] - 0.5) - i0
, 0, 1);
1028 var minB0
= deMath
.clamp((vBounds0
[0] - 0.5) - j0
, 0, 1);
1029 var maxB0
= deMath
.clamp((vBounds0
[1] - 0.5) - j0
, 0, 1);
1032 var c00
= tcuTexture
.remapCubeEdgeCoords(new tcuTexture
.CubeFaceCoords(coords
.face
, [i0
+ 0, j0
+ 0]), size0
);
1033 var c10
= tcuTexture
.remapCubeEdgeCoords(new tcuTexture
.CubeFaceCoords(coords
.face
, [i0
+ 1, j0
+ 0]), size0
);
1034 var c01
= tcuTexture
.remapCubeEdgeCoords(new tcuTexture
.CubeFaceCoords(coords
.face
, [i0
+ 0, j0
+ 1]), size0
);
1035 var c11
= tcuTexture
.remapCubeEdgeCoords(new tcuTexture
.CubeFaceCoords(coords
.face
, [i0
+ 1, j0
+ 1]), size0
);
1037 // If any of samples is out of both edges, implementations can do pretty much anything according to spec.
1038 // \todo [2013-07-08 pyry] Test the special case where all corner pixels have exactly the same color.
1039 if (c00
== null || c01
== null || c10
== null || c11
== null)
1042 depths0
[0] = faces0
[c00
.face
].getPixDepth(c00
.s
, c00
.t
);
1043 depths0
[1] = faces0
[c10
.face
].getPixDepth(c10
.s
, c10
.t
);
1044 depths0
[2] = faces0
[c01
.face
].getPixDepth(c01
.s
, c01
.t
);
1045 depths0
[3] = faces0
[c11
.face
].getPixDepth(c11
.s
, c11
.t
);
1047 for (var j1
= minJ1
; j1
<= maxJ1
; j1
++) {
1048 for (var i1
= minI1
; i1
<= maxI1
; i1
++) {
1049 var minA1
= deMath
.clamp((uBounds1
[0] - 0.5) - i1
, 0, 1);
1050 var maxA1
= deMath
.clamp((uBounds1
[1] - 0.5) - i1
, 0, 1);
1051 var minB1
= deMath
.clamp((vBounds1
[0] - 0.5) - j1
, 0, 1);
1052 var maxB1
= deMath
.clamp((vBounds1
[1] - 0.5) - j1
, 0, 1);
1055 c00
= tcuTexture
.remapCubeEdgeCoords(new tcuTexture
.CubeFaceCoords(coords
.face
, [i1
+ 0, j1
+ 0]), size1
);
1056 c10
= tcuTexture
.remapCubeEdgeCoords(new tcuTexture
.CubeFaceCoords(coords
.face
, [i1
+ 1, j1
+ 0]), size1
);
1057 c01
= tcuTexture
.remapCubeEdgeCoords(new tcuTexture
.CubeFaceCoords(coords
.face
, [i1
+ 0, j1
+ 1]), size1
);
1058 c11
= tcuTexture
.remapCubeEdgeCoords(new tcuTexture
.CubeFaceCoords(coords
.face
, [i1
+ 1, j1
+ 1]), size1
);
1060 if (c00
== null || c01
== null || c10
== null || c11
== null)
1063 depths1
[0] = faces1
[c00
.face
].getPixDepth(c00
.s
, c00
.t
);
1064 depths1
[1] = faces1
[c10
.face
].getPixDepth(c10
.s
, c10
.t
);
1065 depths1
[2] = faces1
[c01
.face
].getPixDepth(c01
.s
, c01
.t
);
1066 depths1
[3] = faces1
[c11
.face
].getPixDepth(c11
.s
, c11
.t
);
1068 if (tcuTexCompareVerifier
.isTrilinearCompareValid(sampler
.compare
, prec
, depths0
, depths1
,
1069 [minA0
, maxA0
], [minB0
, maxB0
],
1070 [minA1
, maxA1
], [minB1
, maxB1
],
1071 fBounds
, cmpReference
, result
, isFixedPointDepth
))
1082 * @param {tcuTexture.TextureCubeView} texture
1083 * @param {number} levelNdx
1084 * @param {tcuTexture.Sampler} sampler
1085 * @param {tcuTexCompareVerifier.TexComparePrecision} prec
1086 * @param {tcuTexture.CubeFaceCoords} coords
1087 * @param {number} cmpReference
1088 * @param {number} result
1092 tcuTexCompareVerifier
.isSeamlessLinearCompareResultValid = function(texture
,
1099 var isFixedPointDepth
= tcuTexCompareVerifier
.isFixedPointDepthTextureFormat(texture
.getLevelFace(levelNdx
, tcuTexture
.CubeFace
.CUBEFACE_NEGATIVE_X
).getFormat());
1100 var size
= texture
.getLevelFace(levelNdx
, coords
.face
).getWidth();
1102 var uBounds
= tcuTexVerifierUtil
.computeNonNormalizedCoordBounds(sampler
.normalizedCoords
, size
, coords
.s
, prec
.coordBits
[0], prec
.uvwBits
[0]);
1103 var vBounds
= tcuTexVerifierUtil
.computeNonNormalizedCoordBounds(sampler
.normalizedCoords
, size
, coords
.t
, prec
.coordBits
[1], prec
.uvwBits
[1]);
1105 // Integer coordinate bounds for (x0,y0) - without wrap mode
1106 var minI
= Math
.floor(uBounds
[0] - 0.5);
1107 var maxI
= Math
.floor(uBounds
[1] - 0.5);
1108 var minJ
= Math
.floor(vBounds
[0] - 0.5);
1109 var maxJ
= Math
.floor(vBounds
[1] - 0.5);
1112 /** @type {Array<tcuTexture.ConstPixelBufferAccess>} */ var faces
= [];
1114 for (var key
in tcuTexture
.CubeFace
) {
1115 var face
= tcuTexture
.CubeFace
[key
];
1116 faces
[face
] = texture
.getLevelFace(levelNdx
, face
);
1119 for (var j
= minJ
; j
<= maxJ
; j
++) {
1120 for (var i
= minI
; i
<= maxI
; i
++) {
1121 var c00
= tcuTexture
.remapCubeEdgeCoords(new tcuTexture
.CubeFaceCoords(coords
.face
, [i
+ 0, j
+ 0]), size
);
1122 var c10
= tcuTexture
.remapCubeEdgeCoords(new tcuTexture
.CubeFaceCoords(coords
.face
, [i
+ 1, j
+ 0]), size
);
1123 var c01
= tcuTexture
.remapCubeEdgeCoords(new tcuTexture
.CubeFaceCoords(coords
.face
, [i
+ 0, j
+ 1]), size
);
1124 var c11
= tcuTexture
.remapCubeEdgeCoords(new tcuTexture
.CubeFaceCoords(coords
.face
, [i
+ 1, j
+ 1]), size
);
1126 // If any of samples is out of both edges, implementations can do pretty much anything according to spec.
1127 // \todo [2013-07-08 pyry] Test the special case where all corner pixels have exactly the same color.
1128 if (!c00
|| !c01
|| !c10
|| !c11
)
1131 // Bounds for filtering factors
1132 var minA
= deMath
.clamp((uBounds
[0] - 0.5) - i
, 0, 1);
1133 var maxA
= deMath
.clamp((uBounds
[1] - 0.5) - i
, 0, 1);
1134 var minB
= deMath
.clamp((vBounds
[0] - 0.5) - j
, 0, 1);
1135 var maxB
= deMath
.clamp((vBounds
[1] - 0.5) - j
, 0, 1);
1138 depths
[0] = faces
[c00
.face
].getPixDepth(c00
.s
, c00
.t
);
1139 depths
[1] = faces
[c10
.face
].getPixDepth(c10
.s
, c10
.t
);
1140 depths
[2] = faces
[c01
.face
].getPixDepth(c01
.s
, c01
.t
);
1141 depths
[3] = faces
[c11
.face
].getPixDepth(c11
.s
, c11
.t
);
1143 if (tcuTexCompareVerifier
.isBilinearCompareValid(sampler
.compare
, prec
, depths
, [minA
, maxA
], [minB
, maxB
], cmpReference
, result
, isFixedPointDepth
))
1152 * @param {tcuTexture.TextureCubeView} texture
1153 * @param {number} levelNdx
1154 * @param {tcuTexture.Sampler} sampler
1155 * @param {tcuTexture.FilterMode} filterMode
1156 * @param {tcuTexCompareVerifier.TexComparePrecision} prec
1157 * @param {tcuTexture.CubeFaceCoords} coords
1158 * @param {number} cmpReference
1159 * @param {number} result
1162 tcuTexCompareVerifier
.isCubeLevelCompareResultValid = function(texture
,
1170 if (filterMode
== tcuTexture
.FilterMode
.LINEAR
) {
1171 if (sampler
.seamlessCubeMap
)
1172 return tcuTexCompareVerifier
.isSeamlessLinearCompareResultValid(texture
, levelNdx
, sampler
, prec
, coords
, cmpReference
, result
);
1174 return tcuTexCompareVerifier
.isLinearCompareResultValid(texture
.getLevelFace(levelNdx
, coords
.face
), sampler
, prec
, [coords
.s
, coords
.t
], 0, cmpReference
, result
);
1176 return tcuTexCompareVerifier
.isNearestCompareResultValid(texture
.getLevelFace(levelNdx
, coords
.face
), sampler
, prec
, [coords
.s
, coords
.t
], 0, cmpReference
, result
);
1180 * @param {tcuTexture.TextureCubeView} texture
1181 * @param {number} baseLevelNdx
1182 * @param {tcuTexture.Sampler} sampler
1183 * @param {tcuTexture.FilterMode} levelFilter
1184 * @param {tcuTexCompareVerifier.TexComparePrecision} prec
1185 * @param {tcuTexture.CubeFaceCoords} coords
1186 * @param {Array<number>} fBounds vec2
1187 * @param {number} cmpReference
1188 * @param {number} result
1191 tcuTexCompareVerifier
.isCubeMipmapLinearCompareResultValid = function(texture
,
1200 if (levelFilter
== tcuTexture
.FilterMode
.LINEAR
) {
1201 if (sampler
.seamlessCubeMap
)
1202 return tcuTexCompareVerifier
.isSeamplessLinearMipmapLinearCompareResultValid(texture
, baseLevelNdx
, sampler
, prec
, coords
, fBounds
, cmpReference
, result
);
1204 return tcuTexCompareVerifier
.isLinearMipmapLinearCompareResultValid(texture
.getLevelFace(baseLevelNdx
, coords
.face
),
1205 texture
.getLevelFace(baseLevelNdx
+ 1, coords
.face
),
1206 sampler
, prec
, [coords
.s
, coords
.t
], 0, fBounds
, cmpReference
, result
);
1208 return tcuTexCompareVerifier
.isNearestMipmapLinearCompareResultValid(texture
.getLevelFace(baseLevelNdx
, coords
.face
),
1209 texture
.getLevelFace(baseLevelNdx
+ 1, coords
.face
),
1210 sampler
, prec
, [coords
.s
, coords
.t
], 0, fBounds
, cmpReference
, result
);
1214 * @param {tcuTexture.TextureCubeView} texture
1215 * @param {tcuTexture.Sampler} sampler
1216 * @param {tcuTexCompareVerifier.TexComparePrecision} prec
1217 * @param {Array<number>} coord vec2 texture coordinates
1218 * @param {Array<number>} lodBounds vec2 level-of-detail bounds
1219 * @param {number} cmpReference
1220 * @param {number} result
1223 tcuTexCompareVerifier
.isTexCompareResultValidCube = function(texture
, sampler
, prec
, coord
, lodBounds
, cmpReference
, result
) {
1224 /** @type {Array<tcuTexture.CubeFace>} */var possibleFaces
= tcuTexVerifierUtil
.getPossibleCubeFaces(coord
, prec
.coordBits
);
1227 return true; // Result is undefined.
1229 for (var tryFaceNdx
= 0; tryFaceNdx
< possibleFaces
.length
; tryFaceNdx
++) {
1230 var face
= possibleFaces
[tryFaceNdx
];
1231 var faceCoords
= new tcuTexture
.CubeFaceCoords(face
, tcuTexture
.projectToFace(face
, coord
));
1232 var minLod
= lodBounds
[0];
1233 var maxLod
= lodBounds
[1];
1234 var canBeMagnified
= minLod
<= sampler
.lodThreshold
;
1235 var canBeMinified
= maxLod
> sampler
.lodThreshold
;
1237 if (canBeMagnified
) {
1238 if (tcuTexCompareVerifier
.isCubeLevelCompareResultValid(texture
, 0, sampler
, sampler
.magFilter
, prec
, faceCoords
, cmpReference
, result
))
1242 if (canBeMinified
) {
1243 var isNearestMipmap
= tcuTexVerifierUtil
.isNearestMipmapFilter(sampler
.minFilter
);
1244 var isLinearMipmap
= tcuTexVerifierUtil
.isLinearMipmapFilter(sampler
.minFilter
);
1245 var minTexLevel
= 0;
1246 var maxTexLevel
= texture
.getNumLevels() - 1;
1248 assertMsgOptions(minTexLevel
< maxTexLevel
, 'Invalid texture levels.', false, true);
1250 if (isLinearMipmap
) {
1251 var minLevel
= deMath
.clamp(Math
.floor(minLod
), minTexLevel
, maxTexLevel
- 1);
1252 var maxLevel
= deMath
.clamp(Math
.floor(maxLod
), minTexLevel
, maxTexLevel
- 1);
1254 assertMsgOptions(minLevel
<= maxLevel
, 'Invalid texture levels.', false, true);
1256 for (var level
= minLevel
; level
<= maxLevel
; level
++) {
1257 var minF
= deMath
.clamp(minLod
- level
, 0, 1);
1258 var maxF
= deMath
.clamp(maxLod
- level
, 0, 1);
1260 if (tcuTexCompareVerifier
.isCubeMipmapLinearCompareResultValid(texture
, level
, sampler
, tcuTexVerifierUtil
.getLevelFilter(sampler
.minFilter
), prec
, faceCoords
, [minF
, maxF
], cmpReference
, result
))
1263 } else if (isNearestMipmap
) {
1264 // \note The accurate formula for nearest mipmapping is level = ceil(lod + 0.5) - 1 but Khronos has made
1265 // decision to allow floor(lod + 0.5) as well.
1266 var minLevel
= deMath
.clamp(Math
.ceil(minLod
+ 0.5) - 1, minTexLevel
, maxTexLevel
);
1267 var maxLevel
= deMath
.clamp(Math
.floor(maxLod
+ 0.5), minTexLevel
, maxTexLevel
);
1269 assertMsgOptions(minLevel
<= maxLevel
, 'Invalid texture levels.', false, true);
1271 for (var level
= minLevel
; level
<= maxLevel
; level
++) {
1272 if (tcuTexCompareVerifier
.isCubeLevelCompareResultValid(texture
, level
, sampler
, tcuTexVerifierUtil
.getLevelFilter(sampler
.minFilter
), prec
, faceCoords
, cmpReference
, result
))
1276 if (tcuTexCompareVerifier
.isCubeLevelCompareResultValid(texture
, 0, sampler
, sampler
.minFilter
, prec
, faceCoords
, cmpReference
, result
))
1286 * @param {tcuTexture.Texture2DArrayView} texture
1287 * @param {tcuTexture.Sampler} sampler
1288 * @param {tcuTexCompareVerifier.TexComparePrecision} prec
1289 * @param {Array<number>} coord vec3 texture coordinates
1290 * @param {Array<number>} lodBounds vec2 level-of-detail bounds
1291 * @param {number} cmpReference
1292 * @param {number} result
1295 tcuTexCompareVerifier
.isTexCompareResultValid2DArray = function(texture
, sampler
, prec
, coord
, lodBounds
, cmpReference
, result
) {
1296 var depthErr
= tcuTexVerifierUtil
.computeFloatingPointError(coord
[2], prec
.coordBits
[2]) + tcuTexVerifierUtil
.computeFixedPointError(prec
.uvwBits
[2]);
1297 var minZ
= coord
[2] - depthErr
;
1298 var maxZ
= coord
[2] + depthErr
;
1299 var minLayer
= deMath
.clamp(Math
.floor(minZ
+ 0.5), 0, texture
.getNumLayers() - 1);
1300 var maxLayer
= deMath
.clamp(Math
.floor(maxZ
+ 0.5), 0, texture
.getNumLayers() - 1);
1302 for (var layer
= minLayer
; layer
<= maxLayer
; layer
++) {
1303 var minLod
= lodBounds
[0];
1304 var maxLod
= lodBounds
[1];
1305 var canBeMagnified
= minLod
<= sampler
.lodThreshold
;
1306 var canBeMinified
= maxLod
> sampler
.lodThreshold
;
1308 if (canBeMagnified
) {
1309 if (tcuTexCompareVerifier
.isLevelCompareResultValid(texture
.getLevel(0), sampler
, sampler
.magFilter
, prec
, deMath
.swizzle(coord
, [0, 1]), layer
, cmpReference
, result
))
1313 if (canBeMinified
) {
1314 var isNearestMipmap
= tcuTexVerifierUtil
.isNearestMipmapFilter(sampler
.minFilter
);
1315 var isLinearMipmap
= tcuTexVerifierUtil
.isLinearMipmapFilter(sampler
.minFilter
);
1316 var minTexLevel
= 0;
1317 var maxTexLevel
= texture
.getNumLevels() - 1;
1319 assertMsgOptions(minTexLevel
< maxTexLevel
, 'Invalid texture levels.', false, true);
1321 if (isLinearMipmap
) {
1322 var minLevel
= deMath
.clamp(Math
.floor(minLod
), minTexLevel
, maxTexLevel
- 1);
1323 var maxLevel
= deMath
.clamp(Math
.floor(maxLod
), minTexLevel
, maxTexLevel
- 1);
1325 assertMsgOptions(minLevel
<= maxLevel
, 'Invalid texture levels.', false, true);
1327 for (var level
= minLevel
; level
<= maxLevel
; level
++) {
1328 var minF
= deMath
.clamp(minLod
- level
, 0, 1);
1329 var maxF
= deMath
.clamp(maxLod
- level
, 0, 1);
1331 if (tcuTexCompareVerifier
.isMipmapLinearCompareResultValid(texture
.getLevel(level
), texture
.getLevel(level
+ 1), sampler
, tcuTexVerifierUtil
.getLevelFilter(sampler
.minFilter
), prec
, deMath
.swizzle(coord
, [0, 1]), layer
, [minF
, maxF
], cmpReference
, result
))
1334 } else if (isNearestMipmap
) {
1335 // \note The accurate formula for nearest mipmapping is level = ceil(lod + 0.5) - 1 but Khronos has made
1336 // decision to allow floor(lod + 0.5) as well.
1337 var minLevel
= deMath
.clamp(Math
.ceil(minLod
+ 0.5) - 1, minTexLevel
, maxTexLevel
);
1338 var maxLevel
= deMath
.clamp(Math
.floor(maxLod
+ 0.5), minTexLevel
, maxTexLevel
);
1340 assertMsgOptions(minLevel
<= maxLevel
, 'Invalid texture levels.', false, true);
1342 for (var level
= minLevel
; level
<= maxLevel
; level
++) {
1343 if (tcuTexCompareVerifier
.isLevelCompareResultValid(texture
.getLevel(level
), sampler
, tcuTexVerifierUtil
.getLevelFilter(sampler
.minFilter
), prec
, deMath
.swizzle(coord
, [0, 1]), layer
, cmpReference
, result
))
1347 if (tcuTexCompareVerifier
.isLevelCompareResultValid(texture
.getLevel(0), sampler
, sampler
.minFilter
, prec
, deMath
.swizzle(coord
, [0, 1]), layer
, cmpReference
, result
))