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 Image comparison utilities.
22 *//*--------------------------------------------------------------------*/
23
24 #include "tcuImageCompare.hpp"
25 #include "tcuSurface.hpp"
26 #include "tcuFuzzyImageCompare.hpp"
27 #include "tcuBilinearImageCompare.hpp"
28 #include "tcuTestLog.hpp"
29 #include "tcuVector.hpp"
30 #include "tcuVectorUtil.hpp"
31 #include "tcuRGBA.hpp"
32 #include "tcuTexture.hpp"
33 #include "tcuTextureUtil.hpp"
34
35 #include <string.h>
36
37 namespace tcu
38 {
39
40 namespace
41 {
42
computeScaleAndBias(const ConstPixelBufferAccess & reference,const ConstPixelBufferAccess & result,tcu::Vec4 & scale,tcu::Vec4 & bias)43 void computeScaleAndBias (const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, tcu::Vec4& scale, tcu::Vec4& bias)
44 {
45 Vec4 minVal;
46 Vec4 maxVal;
47 const float eps = 0.0001f;
48
49 {
50 Vec4 refMin;
51 Vec4 refMax;
52 estimatePixelValueRange(reference, refMin, refMax);
53
54 minVal = refMin;
55 maxVal = refMax;
56 }
57
58 {
59 Vec4 resMin;
60 Vec4 resMax;
61
62 estimatePixelValueRange(result, resMin, resMax);
63
64 minVal[0] = de::min(minVal[0], resMin[0]);
65 minVal[1] = de::min(minVal[1], resMin[1]);
66 minVal[2] = de::min(minVal[2], resMin[2]);
67 minVal[3] = de::min(minVal[3], resMin[3]);
68
69 maxVal[0] = de::max(maxVal[0], resMax[0]);
70 maxVal[1] = de::max(maxVal[1], resMax[1]);
71 maxVal[2] = de::max(maxVal[2], resMax[2]);
72 maxVal[3] = de::max(maxVal[3], resMax[3]);
73 }
74
75 for (int c = 0; c < 4; c++)
76 {
77 if (maxVal[c] - minVal[c] < eps)
78 {
79 scale[c] = (maxVal[c] < eps) ? 1.0f : (1.0f / maxVal[c]);
80 bias[c] = (c == 3) ? (1.0f - maxVal[c]*scale[c]) : (0.0f - minVal[c]*scale[c]);
81 }
82 else
83 {
84 scale[c] = 1.0f / (maxVal[c] - minVal[c]);
85 bias[c] = 0.0f - minVal[c]*scale[c];
86 }
87 }
88 }
89
findNumPositionDeviationFailingPixels(const PixelBufferAccess & errorMask,const ConstPixelBufferAccess & reference,const ConstPixelBufferAccess & result,const UVec4 & threshold,const tcu::IVec3 & maxPositionDeviation,bool acceptOutOfBoundsAsAnyValue)90 static int findNumPositionDeviationFailingPixels (const PixelBufferAccess& errorMask, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, const tcu::IVec3& maxPositionDeviation, bool acceptOutOfBoundsAsAnyValue)
91 {
92 const int width = reference.getWidth();
93 const int height = reference.getHeight();
94 const int depth = reference.getDepth();
95 int numFailingPixels = 0;
96
97 TCU_CHECK_INTERNAL(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth);
98
99 for (int z = 0; z < depth; z++)
100 {
101 for (int y = 0; y < height; y++)
102 {
103 for (int x = 0; x < width; x++)
104 {
105 const IVec4 refPix = reference.getPixelInt(x, y, z);
106 const IVec4 cmpPix = result.getPixelInt(x, y, z);
107
108 // Exact match
109 {
110 const UVec4 diff = abs(refPix - cmpPix).cast<deUint32>();
111 const bool isOk = boolAll(lessThanEqual(diff, threshold));
112
113 if (isOk)
114 {
115 errorMask.setPixel(IVec4(0, 0xff, 0, 0xff), x, y, z);
116 continue;
117 }
118 }
119
120 // Accept over the image bounds pixels since they could be anything
121
122 if (acceptOutOfBoundsAsAnyValue &&
123 (x < maxPositionDeviation.x() || x + maxPositionDeviation.x() >= width ||
124 y < maxPositionDeviation.y() || y + maxPositionDeviation.y() >= height ||
125 z < maxPositionDeviation.z() || z + maxPositionDeviation.z() >= depth))
126 {
127 errorMask.setPixel(IVec4(0, 0xff, 0, 0xff), x, y, z);
128 continue;
129 }
130
131 // Find matching pixels for both result and reference pixel
132
133 {
134 bool pixelFoundForReference = false;
135 bool pixelFoundForResult = false;
136
137 // Find deviated result pixel for reference
138
139 for (int sz = de::max(0, z - maxPositionDeviation.z()); sz <= de::min(depth - 1, z + maxPositionDeviation.z()) && !pixelFoundForReference; ++sz)
140 for (int sy = de::max(0, y - maxPositionDeviation.y()); sy <= de::min(height - 1, y + maxPositionDeviation.y()) && !pixelFoundForReference; ++sy)
141 for (int sx = de::max(0, x - maxPositionDeviation.x()); sx <= de::min(width - 1, x + maxPositionDeviation.x()) && !pixelFoundForReference; ++sx)
142 {
143 const IVec4 deviatedCmpPix = result.getPixelInt(sx, sy, sz);
144 const UVec4 diff = abs(refPix - deviatedCmpPix).cast<deUint32>();
145 const bool isOk = boolAll(lessThanEqual(diff, threshold));
146
147 pixelFoundForReference |= isOk;
148 }
149
150 // Find deviated reference pixel for result
151
152 for (int sz = de::max(0, z - maxPositionDeviation.z()); sz <= de::min(depth - 1, z + maxPositionDeviation.z()) && !pixelFoundForResult; ++sz)
153 for (int sy = de::max(0, y - maxPositionDeviation.y()); sy <= de::min(height - 1, y + maxPositionDeviation.y()) && !pixelFoundForResult; ++sy)
154 for (int sx = de::max(0, x - maxPositionDeviation.x()); sx <= de::min(width - 1, x + maxPositionDeviation.x()) && !pixelFoundForResult; ++sx)
155 {
156 const IVec4 deviatedRefPix = reference.getPixelInt(sx, sy, sz);
157 const UVec4 diff = abs(cmpPix - deviatedRefPix).cast<deUint32>();
158 const bool isOk = boolAll(lessThanEqual(diff, threshold));
159
160 pixelFoundForResult |= isOk;
161 }
162
163 if (pixelFoundForReference && pixelFoundForResult)
164 errorMask.setPixel(IVec4(0, 0xff, 0, 0xff), x, y, z);
165 else
166 {
167 errorMask.setPixel(IVec4(0xff, 0, 0, 0xff), x, y, z);
168 ++numFailingPixels;
169 }
170 }
171 }
172 }
173 }
174
175 return numFailingPixels;
176 }
177
178 } // anonymous
179
180 /*--------------------------------------------------------------------*//*!
181 * \brief Fuzzy image comparison
182 *
183 * This image comparison is designed for comparing images rendered by 3D
184 * graphics APIs such as OpenGL. The comparison allows small local differences
185 * and compensates for aliasing.
186 *
187 * The algorithm first performs light blurring on both images and then
188 * does per-pixel analysis. Pixels are compared to 3x3 bilinear surface
189 * defined by adjecent pixels. This compensates for both 1-pixel deviations
190 * in geometry and aliasing in texture data.
191 *
192 * Error metric is computed based on the differences. On valid images the
193 * metric is usually <0.01. Thus good threshold values are in range 0.02 to
194 * 0.05.
195 *
196 * On failure error image is generated that shows where the failing pixels
197 * are.
198 *
199 * \note Currently supports only UNORM_INT8 formats
200 * \param log Test log for results
201 * \param imageSetName Name for image set when logging results
202 * \param imageSetDesc Description for image set
203 * \param reference Reference image
204 * \param result Result image
205 * \param threshold Error metric threshold (good values are 0.02-0.05)
206 * \param logMode Logging mode
207 * \return true if comparison passes, false otherwise
208 *//*--------------------------------------------------------------------*/
fuzzyCompare(TestLog & log,const char * imageSetName,const char * imageSetDesc,const ConstPixelBufferAccess & reference,const ConstPixelBufferAccess & result,float threshold,CompareLogMode logMode)209 bool fuzzyCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, float threshold, CompareLogMode logMode)
210 {
211 FuzzyCompareParams params; // Use defaults.
212 TextureLevel errorMask (TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), reference.getWidth(), reference.getHeight());
213 float difference = fuzzyCompare(params, reference, result, errorMask.getAccess());
214 bool isOk = difference <= threshold;
215 Vec4 pixelBias (0.0f, 0.0f, 0.0f, 0.0f);
216 Vec4 pixelScale (1.0f, 1.0f, 1.0f, 1.0f);
217
218 if (!isOk || logMode == COMPARE_LOG_EVERYTHING)
219 {
220 // Generate more accurate error mask.
221 params.maxSampleSkip = 0;
222 fuzzyCompare(params, reference, result, errorMask.getAccess());
223
224 if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8) && reference.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
225 computeScaleAndBias(reference, result, pixelScale, pixelBias);
226
227 if (!isOk)
228 log << TestLog::Message << "Image comparison failed: difference = " << difference << ", threshold = " << threshold << TestLog::EndMessage;
229
230 log << TestLog::ImageSet(imageSetName, imageSetDesc)
231 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
232 << TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
233 << TestLog::Image("ErrorMask", "Error mask", errorMask)
234 << TestLog::EndImageSet;
235 }
236 else if (logMode == COMPARE_LOG_RESULT)
237 {
238 if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
239 computePixelScaleBias(result, pixelScale, pixelBias);
240
241 log << TestLog::ImageSet(imageSetName, imageSetDesc)
242 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
243 << TestLog::EndImageSet;
244 }
245
246 return isOk;
247 }
248
249 /*--------------------------------------------------------------------*//*!
250 * \brief Fuzzy image comparison
251 *
252 * This image comparison is designed for comparing images rendered by 3D
253 * graphics APIs such as OpenGL. The comparison allows small local differences
254 * and compensates for aliasing.
255 *
256 * The algorithm first performs light blurring on both images and then
257 * does per-pixel analysis. Pixels are compared to 3x3 bilinear surface
258 * defined by adjecent pixels. This compensates for both 1-pixel deviations
259 * in geometry and aliasing in texture data.
260 *
261 * Error metric is computed based on the differences. On valid images the
262 * metric is usually <0.01. Thus good threshold values are in range 0.02 to
263 * 0.05.
264 *
265 * On failure error image is generated that shows where the failing pixels
266 * are.
267 *
268 * \note Currently supports only UNORM_INT8 formats
269 * \param log Test log for results
270 * \param imageSetName Name for image set when logging results
271 * \param imageSetDesc Description for image set
272 * \param reference Reference image
273 * \param result Result image
274 * \param threshold Error metric threshold (good values are 0.02-0.05)
275 * \param logMode Logging mode
276 * \return true if comparison passes, false otherwise
277 *//*--------------------------------------------------------------------*/
fuzzyCompare(TestLog & log,const char * imageSetName,const char * imageSetDesc,const Surface & reference,const Surface & result,float threshold,CompareLogMode logMode)278 bool fuzzyCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const Surface& reference, const Surface& result, float threshold, CompareLogMode logMode)
279 {
280 return fuzzyCompare(log, imageSetName, imageSetDesc, reference.getAccess(), result.getAccess(), threshold, logMode);
281 }
282
computeSquaredDiffSum(const ConstPixelBufferAccess & ref,const ConstPixelBufferAccess & cmp,const PixelBufferAccess & diffMask,int diffFactor)283 static deInt64 computeSquaredDiffSum (const ConstPixelBufferAccess& ref, const ConstPixelBufferAccess& cmp, const PixelBufferAccess& diffMask, int diffFactor)
284 {
285 TCU_CHECK_INTERNAL(ref.getFormat().type == TextureFormat::UNORM_INT8 && cmp.getFormat().type == TextureFormat::UNORM_INT8);
286 DE_ASSERT(ref.getWidth() == cmp.getWidth() && ref.getWidth() == diffMask.getWidth());
287 DE_ASSERT(ref.getHeight() == cmp.getHeight() && ref.getHeight() == diffMask.getHeight());
288
289 deInt64 diffSum = 0;
290
291 for (int y = 0; y < cmp.getHeight(); y++)
292 {
293 for (int x = 0; x < cmp.getWidth(); x++)
294 {
295 IVec4 a = ref.getPixelInt(x, y);
296 IVec4 b = cmp.getPixelInt(x, y);
297 IVec4 diff = abs(a - b);
298 int sum = diff.x() + diff.y() + diff.z() + diff.w();
299 int sqSum = diff.x()*diff.x() + diff.y()*diff.y() + diff.z()*diff.z() + diff.w()*diff.w();
300
301 diffMask.setPixel(tcu::RGBA(deClamp32(sum*diffFactor, 0, 255), deClamp32(255-sum*diffFactor, 0, 255), 0, 255).toVec(), x, y);
302
303 diffSum += (deInt64)sqSum;
304 }
305 }
306
307 return diffSum;
308 }
309
310 /*--------------------------------------------------------------------*//*!
311 * \brief Per-pixel difference accuracy metric
312 *
313 * Computes accuracy metric using per-pixel differences between reference
314 * and result images.
315 *
316 * \note Supports only integer- and fixed-point formats
317 * \param log Test log for results
318 * \param imageSetName Name for image set when logging results
319 * \param imageSetDesc Description for image set
320 * \param reference Reference image
321 * \param result Result image
322 * \param bestScoreDiff Scaling factor
323 * \param worstScoreDiff Scaling factor
324 * \param logMode Logging mode
325 * \return true if comparison passes, false otherwise
326 *//*--------------------------------------------------------------------*/
measurePixelDiffAccuracy(TestLog & log,const char * imageSetName,const char * imageSetDesc,const ConstPixelBufferAccess & reference,const ConstPixelBufferAccess & result,int bestScoreDiff,int worstScoreDiff,CompareLogMode logMode)327 int measurePixelDiffAccuracy (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, int bestScoreDiff, int worstScoreDiff, CompareLogMode logMode)
328 {
329 TextureLevel diffMask (TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), reference.getWidth(), reference.getHeight());
330 int diffFactor = 8;
331 deInt64 squaredSum = computeSquaredDiffSum(reference, result, diffMask.getAccess(), diffFactor);
332 float sum = deFloatSqrt((float)squaredSum);
333 int score = deClamp32(deFloorFloatToInt32(100.0f - (de::max(sum-(float)bestScoreDiff, 0.0f) / (float)(worstScoreDiff-bestScoreDiff))*100.0f), 0, 100);
334 const int failThreshold = 10;
335 Vec4 pixelBias (0.0f, 0.0f, 0.0f, 0.0f);
336 Vec4 pixelScale (1.0f, 1.0f, 1.0f, 1.0f);
337
338 if (logMode == COMPARE_LOG_EVERYTHING || score <= failThreshold)
339 {
340 if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8) && reference.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
341 computeScaleAndBias(reference, result, pixelScale, pixelBias);
342
343 log << TestLog::ImageSet(imageSetName, imageSetDesc)
344 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
345 << TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
346 << TestLog::Image("DiffMask", "Difference", diffMask)
347 << TestLog::EndImageSet;
348 }
349 else if (logMode == COMPARE_LOG_RESULT)
350 {
351 if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
352 computePixelScaleBias(result, pixelScale, pixelBias);
353
354 log << TestLog::ImageSet(imageSetName, imageSetDesc)
355 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
356 << TestLog::EndImageSet;
357 }
358
359 if (logMode != COMPARE_LOG_ON_ERROR || score <= failThreshold)
360 log << TestLog::Integer("DiffSum", "Squared difference sum", "", QP_KEY_TAG_NONE, squaredSum)
361 << TestLog::Integer("Score", "Score", "", QP_KEY_TAG_QUALITY, score);
362
363 return score;
364 }
365
366 /*--------------------------------------------------------------------*//*!
367 * \brief Per-pixel difference accuracy metric
368 *
369 * Computes accuracy metric using per-pixel differences between reference
370 * and result images.
371 *
372 * \note Supports only integer- and fixed-point formats
373 * \param log Test log for results
374 * \param imageSetName Name for image set when logging results
375 * \param imageSetDesc Description for image set
376 * \param reference Reference image
377 * \param result Result image
378 * \param bestScoreDiff Scaling factor
379 * \param worstScoreDiff Scaling factor
380 * \param logMode Logging mode
381 * \return true if comparison passes, false otherwise
382 *//*--------------------------------------------------------------------*/
measurePixelDiffAccuracy(TestLog & log,const char * imageSetName,const char * imageSetDesc,const Surface & reference,const Surface & result,int bestScoreDiff,int worstScoreDiff,CompareLogMode logMode)383 int measurePixelDiffAccuracy (TestLog& log, const char* imageSetName, const char* imageSetDesc, const Surface& reference, const Surface& result, int bestScoreDiff, int worstScoreDiff, CompareLogMode logMode)
384 {
385 return measurePixelDiffAccuracy(log, imageSetName, imageSetDesc, reference.getAccess(), result.getAccess(), bestScoreDiff, worstScoreDiff, logMode);
386 }
387
388 /*--------------------------------------------------------------------*//*!
389 * \brief Per-pixel threshold-based comparison
390 *
391 * This compare computes per-pixel differences between result and reference
392 * image. Comparison fails if any pixels exceed the given threshold value.
393 *
394 * This comparison uses ULP (units in last place) metric for computing the
395 * difference between floating-point values and thus this function can
396 * be used only for comparing floating-point texture data.
397 *
398 * On failure error image is generated that shows where the failing pixels
399 * are.
400 *
401 * \param log Test log for results
402 * \param imageSetName Name for image set when logging results
403 * \param imageSetDesc Description for image set
404 * \param reference Reference image
405 * \param result Result image
406 * \param threshold Maximum allowed difference
407 * \param logMode Logging mode
408 * \return true if comparison passes, false otherwise
409 *//*--------------------------------------------------------------------*/
floatUlpThresholdCompare(TestLog & log,const char * imageSetName,const char * imageSetDesc,const ConstPixelBufferAccess & reference,const ConstPixelBufferAccess & result,const UVec4 & threshold,CompareLogMode logMode)410 bool floatUlpThresholdCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, CompareLogMode logMode)
411 {
412 int width = reference.getWidth();
413 int height = reference.getHeight();
414 int depth = reference.getDepth();
415 TextureLevel errorMaskStorage (TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
416 PixelBufferAccess errorMask = errorMaskStorage.getAccess();
417 UVec4 maxDiff (0, 0, 0, 0);
418 Vec4 pixelBias (0.0f, 0.0f, 0.0f, 0.0f);
419 Vec4 pixelScale (1.0f, 1.0f, 1.0f, 1.0f);
420
421 TCU_CHECK(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth);
422
423 for (int z = 0; z < depth; z++)
424 {
425 for (int y = 0; y < height; y++)
426 {
427 for (int x = 0; x < width; x++)
428 {
429 Vec4 refPix = reference.getPixel(x, y, z);
430 Vec4 cmpPix = result.getPixel(x, y, z);
431 UVec4 refBits;
432 UVec4 cmpBits;
433
434 // memcpy() is the way to do float->uint32 reinterpretation.
435 memcpy(refBits.getPtr(), refPix.getPtr(), 4*sizeof(deUint32));
436 memcpy(cmpBits.getPtr(), cmpPix.getPtr(), 4*sizeof(deUint32));
437
438 UVec4 diff = abs(refBits.cast<int>() - cmpBits.cast<int>()).cast<deUint32>();
439 bool isOk = boolAll(lessThanEqual(diff, threshold));
440
441 maxDiff = max(maxDiff, diff);
442
443 errorMask.setPixel(isOk ? Vec4(0.0f, 1.0f, 0.0f, 1.0f) : Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
444 }
445 }
446 }
447
448 bool compareOk = boolAll(lessThanEqual(maxDiff, threshold));
449
450 if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
451 {
452 // All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
453 if (tcu::getTextureChannelClass(reference.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
454 tcu::getTextureChannelClass(result.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
455 {
456 computeScaleAndBias(reference, result, pixelScale, pixelBias);
457 log << TestLog::Message << "Result and reference images are normalized with formula p * " << pixelScale << " + " << pixelBias << TestLog::EndMessage;
458 }
459
460 if (!compareOk)
461 log << TestLog::Message << "Image comparison failed: max difference = " << maxDiff << ", threshold = " << threshold << TestLog::EndMessage;
462
463 log << TestLog::ImageSet(imageSetName, imageSetDesc)
464 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
465 << TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
466 << TestLog::Image("ErrorMask", "Error mask", errorMask)
467 << TestLog::EndImageSet;
468 }
469 else if (logMode == COMPARE_LOG_RESULT)
470 {
471 if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
472 computePixelScaleBias(result, pixelScale, pixelBias);
473
474 log << TestLog::ImageSet(imageSetName, imageSetDesc)
475 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
476 << TestLog::EndImageSet;
477 }
478
479 return compareOk;
480 }
481
482 /*--------------------------------------------------------------------*//*!
483 * \brief Per-pixel threshold-based comparison
484 *
485 * This compare computes per-pixel differences between result and reference
486 * image. Comparison fails if any pixels exceed the given threshold value.
487 *
488 * This comparison can be used for floating-point and fixed-point formats.
489 * Difference is computed in floating-point space.
490 *
491 * On failure an error image is generated that shows where the failing
492 * pixels are.
493 *
494 * \param log Test log for results
495 * \param imageSetName Name for image set when logging results
496 * \param imageSetDesc Description for image set
497 * \param reference Reference image
498 * \param result Result image
499 * \param threshold Maximum allowed difference
500 * \param logMode Logging mode
501 * \return true if comparison passes, false otherwise
502 *//*--------------------------------------------------------------------*/
floatThresholdCompare(TestLog & log,const char * imageSetName,const char * imageSetDesc,const ConstPixelBufferAccess & reference,const ConstPixelBufferAccess & result,const Vec4 & threshold,CompareLogMode logMode)503 bool floatThresholdCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const Vec4& threshold, CompareLogMode logMode)
504 {
505 int width = reference.getWidth();
506 int height = reference.getHeight();
507 int depth = reference.getDepth();
508 TextureLevel errorMaskStorage (TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
509 PixelBufferAccess errorMask = errorMaskStorage.getAccess();
510 Vec4 maxDiff (0.0f, 0.0f, 0.0f, 0.0f);
511 Vec4 pixelBias (0.0f, 0.0f, 0.0f, 0.0f);
512 Vec4 pixelScale (1.0f, 1.0f, 1.0f, 1.0f);
513
514 TCU_CHECK_INTERNAL(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth);
515
516 for (int z = 0; z < depth; z++)
517 {
518 for (int y = 0; y < height; y++)
519 {
520 for (int x = 0; x < width; x++)
521 {
522 Vec4 refPix = reference.getPixel(x, y, z);
523 Vec4 cmpPix = result.getPixel(x, y, z);
524
525 Vec4 diff = abs(refPix - cmpPix);
526 bool isOk = boolAll(lessThanEqual(diff, threshold));
527
528 maxDiff = max(maxDiff, diff);
529
530 errorMask.setPixel(isOk ? Vec4(0.0f, 1.0f, 0.0f, 1.0f) : Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
531 }
532 }
533 }
534
535 bool compareOk = boolAll(lessThanEqual(maxDiff, threshold));
536
537 if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
538 {
539 // All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
540 if (tcu::getTextureChannelClass(reference.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
541 tcu::getTextureChannelClass(result.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
542 {
543 computeScaleAndBias(reference, result, pixelScale, pixelBias);
544 log << TestLog::Message << "Result and reference images are normalized with formula p * " << pixelScale << " + " << pixelBias << TestLog::EndMessage;
545 }
546
547 if (!compareOk)
548 log << TestLog::Message << "Image comparison failed: max difference = " << maxDiff << ", threshold = " << threshold << TestLog::EndMessage;
549
550 log << TestLog::ImageSet(imageSetName, imageSetDesc)
551 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
552 << TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
553 << TestLog::Image("ErrorMask", "Error mask", errorMask)
554 << TestLog::EndImageSet;
555 }
556 else if (logMode == COMPARE_LOG_RESULT)
557 {
558 if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
559 computePixelScaleBias(result, pixelScale, pixelBias);
560
561 log << TestLog::ImageSet(imageSetName, imageSetDesc)
562 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
563 << TestLog::EndImageSet;
564 }
565
566 return compareOk;
567 }
568
569 /*--------------------------------------------------------------------*//*!
570 * \brief Per-pixel threshold-based comparison
571 *
572 * This compare computes per-pixel differences between result and reference
573 * color. Comparison fails if any pixels exceed the given threshold value.
574 *
575 * This comparison can be used for floating-point and fixed-point formats.
576 * Difference is computed in floating-point space.
577 *
578 * On failure an error image is generated that shows where the failing
579 * pixels are.
580 *
581 * \param log Test log for results
582 * \param imageSetName Name for image set when logging results
583 * \param imageSetDesc Description for image set
584 * \param reference Reference color
585 * \param result Result image
586 * \param threshold Maximum allowed difference
587 * \param logMode Logging mode
588 * \return true if comparison passes, false otherwise
589 *//*--------------------------------------------------------------------*/
floatThresholdCompare(TestLog & log,const char * imageSetName,const char * imageSetDesc,const Vec4 & reference,const ConstPixelBufferAccess & result,const Vec4 & threshold,CompareLogMode logMode)590 bool floatThresholdCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const Vec4& reference, const ConstPixelBufferAccess& result, const Vec4& threshold, CompareLogMode logMode)
591 {
592 const int width = result.getWidth();
593 const int height = result.getHeight();
594 const int depth = result.getDepth();
595
596 TextureLevel errorMaskStorage (TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
597 PixelBufferAccess errorMask = errorMaskStorage.getAccess();
598 Vec4 maxDiff (0.0f, 0.0f, 0.0f, 0.0f);
599 Vec4 pixelBias (0.0f, 0.0f, 0.0f, 0.0f);
600 Vec4 pixelScale (1.0f, 1.0f, 1.0f, 1.0f);
601
602 for (int z = 0; z < depth; z++)
603 {
604 for (int y = 0; y < height; y++)
605 {
606 for (int x = 0; x < width; x++)
607 {
608 const Vec4 cmpPix = result.getPixel(x, y, z);
609 const Vec4 diff = abs(reference - cmpPix);
610 const bool isOk = boolAll(lessThanEqual(diff, threshold));
611
612 maxDiff = max(maxDiff, diff);
613
614 errorMask.setPixel(isOk ? Vec4(0.0f, 1.0f, 0.0f, 1.0f) : Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
615 }
616 }
617 }
618
619 bool compareOk = boolAll(lessThanEqual(maxDiff, threshold));
620
621 if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
622 {
623 // All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
624 if (tcu::getTextureChannelClass(result.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
625 {
626 computeScaleAndBias(result, result, pixelScale, pixelBias);
627 log << TestLog::Message << "Result image is normalized with formula p * " << pixelScale << " + " << pixelBias << TestLog::EndMessage;
628 }
629
630 if (!compareOk)
631 log << TestLog::Message << "Image comparison failed: max difference = " << maxDiff << ", threshold = " << threshold << ", reference = " << reference << TestLog::EndMessage;
632
633 log << TestLog::ImageSet(imageSetName, imageSetDesc)
634 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
635 << TestLog::Image("ErrorMask", "Error mask", errorMask)
636 << TestLog::EndImageSet;
637 }
638 else if (logMode == COMPARE_LOG_RESULT)
639 {
640 if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
641 computePixelScaleBias(result, pixelScale, pixelBias);
642
643 log << TestLog::ImageSet(imageSetName, imageSetDesc)
644 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
645 << TestLog::EndImageSet;
646 }
647
648 return compareOk;
649 }
650
651 /*--------------------------------------------------------------------*//*!
652 * \brief Per-pixel threshold-based comparison
653 *
654 * This compare computes per-pixel differences between result and reference
655 * image. Comparison fails if any pixels exceed the given threshold value.
656 *
657 * This comparison can be used for integer- and fixed-point texture formats.
658 * Difference is computed in integer space.
659 *
660 * On failure error image is generated that shows where the failing pixels
661 * are.
662 *
663 * \param log Test log for results
664 * \param imageSetName Name for image set when logging results
665 * \param imageSetDesc Description for image set
666 * \param reference Reference image
667 * \param result Result image
668 * \param threshold Maximum allowed difference
669 * \param logMode Logging mode
670 * \return true if comparison passes, false otherwise
671 *//*--------------------------------------------------------------------*/
intThresholdCompare(TestLog & log,const char * imageSetName,const char * imageSetDesc,const ConstPixelBufferAccess & reference,const ConstPixelBufferAccess & result,const UVec4 & threshold,CompareLogMode logMode)672 bool intThresholdCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, CompareLogMode logMode)
673 {
674 int width = reference.getWidth();
675 int height = reference.getHeight();
676 int depth = reference.getDepth();
677 TextureLevel errorMaskStorage (TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
678 PixelBufferAccess errorMask = errorMaskStorage.getAccess();
679 UVec4 maxDiff (0, 0, 0, 0);
680 Vec4 pixelBias (0.0f, 0.0f, 0.0f, 0.0f);
681 Vec4 pixelScale (1.0f, 1.0f, 1.0f, 1.0f);
682
683 TCU_CHECK_INTERNAL(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth);
684
685 for (int z = 0; z < depth; z++)
686 {
687 for (int y = 0; y < height; y++)
688 {
689 for (int x = 0; x < width; x++)
690 {
691 IVec4 refPix = reference.getPixelInt(x, y, z);
692 IVec4 cmpPix = result.getPixelInt(x, y, z);
693
694 UVec4 diff = abs(refPix - cmpPix).cast<deUint32>();
695 bool isOk = boolAll(lessThanEqual(diff, threshold));
696
697 maxDiff = max(maxDiff, diff);
698
699 errorMask.setPixel(isOk ? IVec4(0, 0xff, 0, 0xff) : IVec4(0xff, 0, 0, 0xff), x, y, z);
700 }
701 }
702 }
703
704 bool compareOk = boolAll(lessThanEqual(maxDiff, threshold));
705
706 if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
707 {
708 // All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
709 if (tcu::getTextureChannelClass(reference.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
710 tcu::getTextureChannelClass(result.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
711 {
712 computeScaleAndBias(reference, result, pixelScale, pixelBias);
713 log << TestLog::Message << "Result and reference images are normalized with formula p * " << pixelScale << " + " << pixelBias << TestLog::EndMessage;
714 }
715
716 if (!compareOk)
717 log << TestLog::Message << "Image comparison failed: max difference = " << maxDiff << ", threshold = " << threshold << TestLog::EndMessage;
718
719 log << TestLog::ImageSet(imageSetName, imageSetDesc)
720 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
721 << TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
722 << TestLog::Image("ErrorMask", "Error mask", errorMask)
723 << TestLog::EndImageSet;
724 }
725 else if (logMode == COMPARE_LOG_RESULT)
726 {
727 if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
728 computePixelScaleBias(result, pixelScale, pixelBias);
729
730 log << TestLog::ImageSet(imageSetName, imageSetDesc)
731 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
732 << TestLog::EndImageSet;
733 }
734
735 return compareOk;
736 }
737
738 /*--------------------------------------------------------------------*//*!
739 * \brief Per-pixel threshold-based deviation-ignoring comparison
740 *
741 * This compare computes per-pixel differences between result and reference
742 * image. Comparison fails if there is no pixel matching the given threshold
743 * value in the search volume.
744 *
745 * If the search volume contains out-of-bounds pixels, comparison can be set
746 * to either ignore these pixels in search or to accept any pixel that has
747 * out-of-bounds pixels in its search volume.
748 *
749 * This comparison can be used for integer- and fixed-point texture formats.
750 * Difference is computed in integer space.
751 *
752 * On failure error image is generated that shows where the failing pixels
753 * are.
754 *
755 * \param log Test log for results
756 * \param imageSetName Name for image set when logging results
757 * \param imageSetDesc Description for image set
758 * \param reference Reference image
759 * \param result Result image
760 * \param threshold Maximum allowed difference
761 * \param maxPositionDeviation Maximum allowed distance in the search
762 * volume.
763 * \param acceptOutOfBoundsAsAnyValue Accept any pixel in the boundary region
764 * \param logMode Logging mode
765 * \return true if comparison passes, false otherwise
766 *//*--------------------------------------------------------------------*/
intThresholdPositionDeviationCompare(TestLog & log,const char * imageSetName,const char * imageSetDesc,const ConstPixelBufferAccess & reference,const ConstPixelBufferAccess & result,const UVec4 & threshold,const tcu::IVec3 & maxPositionDeviation,bool acceptOutOfBoundsAsAnyValue,CompareLogMode logMode)767 bool intThresholdPositionDeviationCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, const tcu::IVec3& maxPositionDeviation, bool acceptOutOfBoundsAsAnyValue, CompareLogMode logMode)
768 {
769 const int width = reference.getWidth();
770 const int height = reference.getHeight();
771 const int depth = reference.getDepth();
772 TextureLevel errorMaskStorage (TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
773 PixelBufferAccess errorMask = errorMaskStorage.getAccess();
774 const int numFailingPixels = findNumPositionDeviationFailingPixels(errorMask, reference, result, threshold, maxPositionDeviation, acceptOutOfBoundsAsAnyValue);
775 const bool compareOk = numFailingPixels == 0;
776 Vec4 pixelBias (0.0f, 0.0f, 0.0f, 0.0f);
777 Vec4 pixelScale (1.0f, 1.0f, 1.0f, 1.0f);
778
779 if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
780 {
781 // All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
782 if (tcu::getTextureChannelClass(reference.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
783 tcu::getTextureChannelClass(result.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
784 {
785 computeScaleAndBias(reference, result, pixelScale, pixelBias);
786 log << TestLog::Message << "Result and reference images are normalized with formula p * " << pixelScale << " + " << pixelBias << TestLog::EndMessage;
787 }
788
789 if (!compareOk)
790 log << TestLog::Message
791 << "Image comparison failed:\n"
792 << "\tallowed position deviation = " << maxPositionDeviation << "\n"
793 << "\tcolor threshold = " << threshold
794 << TestLog::EndMessage;
795
796 log << TestLog::ImageSet(imageSetName, imageSetDesc)
797 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
798 << TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
799 << TestLog::Image("ErrorMask", "Error mask", errorMask)
800 << TestLog::EndImageSet;
801 }
802 else if (logMode == COMPARE_LOG_RESULT)
803 {
804 if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
805 computePixelScaleBias(result, pixelScale, pixelBias);
806
807 log << TestLog::ImageSet(imageSetName, imageSetDesc)
808 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
809 << TestLog::EndImageSet;
810 }
811
812 return compareOk;
813 }
814
815 /*--------------------------------------------------------------------*//*!
816 * \brief Per-pixel threshold-based deviation-ignoring comparison
817 *
818 * This compare computes per-pixel differences between result and reference
819 * image. Pixel fails the test if there is no pixel matching the given
820 * threshold value in the search volume. Comparison fails if the number of
821 * failing pixels exceeds the given limit.
822 *
823 * If the search volume contains out-of-bounds pixels, comparison can be set
824 * to either ignore these pixels in search or to accept any pixel that has
825 * out-of-bounds pixels in its search volume.
826 *
827 * This comparison can be used for integer- and fixed-point texture formats.
828 * Difference is computed in integer space.
829 *
830 * On failure error image is generated that shows where the failing pixels
831 * are.
832 *
833 * \param log Test log for results
834 * \param imageSetName Name for image set when logging results
835 * \param imageSetDesc Description for image set
836 * \param reference Reference image
837 * \param result Result image
838 * \param threshold Maximum allowed difference
839 * \param maxPositionDeviation Maximum allowed distance in the search
840 * volume.
841 * \param acceptOutOfBoundsAsAnyValue Accept any pixel in the boundary region
842 * \param maxAllowedFailingPixels Maximum number of failing pixels
843 * \param logMode Logging mode
844 * \return true if comparison passes, false otherwise
845 *//*--------------------------------------------------------------------*/
intThresholdPositionDeviationErrorThresholdCompare(TestLog & log,const char * imageSetName,const char * imageSetDesc,const ConstPixelBufferAccess & reference,const ConstPixelBufferAccess & result,const UVec4 & threshold,const tcu::IVec3 & maxPositionDeviation,bool acceptOutOfBoundsAsAnyValue,int maxAllowedFailingPixels,CompareLogMode logMode)846 bool intThresholdPositionDeviationErrorThresholdCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, const tcu::IVec3& maxPositionDeviation, bool acceptOutOfBoundsAsAnyValue, int maxAllowedFailingPixels, CompareLogMode logMode)
847 {
848 const int width = reference.getWidth();
849 const int height = reference.getHeight();
850 const int depth = reference.getDepth();
851 TextureLevel errorMaskStorage (TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
852 PixelBufferAccess errorMask = errorMaskStorage.getAccess();
853 const int numFailingPixels = findNumPositionDeviationFailingPixels(errorMask, reference, result, threshold, maxPositionDeviation, acceptOutOfBoundsAsAnyValue);
854 const bool compareOk = numFailingPixels <= maxAllowedFailingPixels;
855 Vec4 pixelBias (0.0f, 0.0f, 0.0f, 0.0f);
856 Vec4 pixelScale (1.0f, 1.0f, 1.0f, 1.0f);
857
858 if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
859 {
860 // All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
861 if (tcu::getTextureChannelClass(reference.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
862 tcu::getTextureChannelClass(result.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
863 {
864 computeScaleAndBias(reference, result, pixelScale, pixelBias);
865 log << TestLog::Message << "Result and reference images are normalized with formula p * " << pixelScale << " + " << pixelBias << TestLog::EndMessage;
866 }
867
868 if (!compareOk)
869 log << TestLog::Message
870 << "Image comparison failed:\n"
871 << "\tallowed position deviation = " << maxPositionDeviation << "\n"
872 << "\tcolor threshold = " << threshold
873 << TestLog::EndMessage;
874 log << TestLog::Message << "Number of failing pixels = " << numFailingPixels << ", max allowed = " << maxAllowedFailingPixels << TestLog::EndMessage;
875
876 log << TestLog::ImageSet(imageSetName, imageSetDesc)
877 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
878 << TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
879 << TestLog::Image("ErrorMask", "Error mask", errorMask)
880 << TestLog::EndImageSet;
881 }
882 else if (logMode == COMPARE_LOG_RESULT)
883 {
884 if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
885 computePixelScaleBias(result, pixelScale, pixelBias);
886
887 log << TestLog::ImageSet(imageSetName, imageSetDesc)
888 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
889 << TestLog::EndImageSet;
890 }
891
892 return compareOk;
893 }
894
895 /*--------------------------------------------------------------------*//*!
896 * \brief Per-pixel threshold-based comparison
897 *
898 * This compare computes per-pixel differences between result and reference
899 * image. Comparison fails if any pixels exceed the given threshold value.
900 *
901 * On failure error image is generated that shows where the failing pixels
902 * are.
903 *
904 * \param log Test log for results
905 * \param imageSetName Name for image set when logging results
906 * \param imageSetDesc Description for image set
907 * \param reference Reference image
908 * \param result Result image
909 * \param threshold Maximum allowed difference
910 * \param logMode Logging mode
911 * \return true if comparison passes, false otherwise
912 *//*--------------------------------------------------------------------*/
pixelThresholdCompare(TestLog & log,const char * imageSetName,const char * imageSetDesc,const Surface & reference,const Surface & result,const RGBA & threshold,CompareLogMode logMode)913 bool pixelThresholdCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const Surface& reference, const Surface& result, const RGBA& threshold, CompareLogMode logMode)
914 {
915 return intThresholdCompare(log, imageSetName, imageSetDesc, reference.getAccess(), result.getAccess(), threshold.toIVec().cast<deUint32>(), logMode);
916 }
917
918 /*--------------------------------------------------------------------*//*!
919 * \brief Bilinear image comparison
920 *
921 * \todo [pyry] Describe
922 *
923 * On failure error image is generated that shows where the failing pixels
924 * are.
925 *
926 * \note Currently supports only RGBA, UNORM_INT8 formats
927 * \param log Test log for results
928 * \param imageSetName Name for image set when logging results
929 * \param imageSetDesc Description for image set
930 * \param reference Reference image
931 * \param result Result image
932 * \param threshold Maximum local difference
933 * \param logMode Logging mode
934 * \return true if comparison passes, false otherwise
935 *//*--------------------------------------------------------------------*/
bilinearCompare(TestLog & log,const char * imageSetName,const char * imageSetDesc,const ConstPixelBufferAccess & reference,const ConstPixelBufferAccess & result,const RGBA threshold,CompareLogMode logMode)936 bool bilinearCompare (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const RGBA threshold, CompareLogMode logMode)
937 {
938 TextureLevel errorMask (TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), reference.getWidth(), reference.getHeight());
939 bool isOk = bilinearCompare(reference, result, errorMask, threshold);
940 Vec4 pixelBias (0.0f, 0.0f, 0.0f, 0.0f);
941 Vec4 pixelScale (1.0f, 1.0f, 1.0f, 1.0f);
942
943 if (!isOk || logMode == COMPARE_LOG_EVERYTHING)
944 {
945 if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8) && reference.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
946 computeScaleAndBias(reference, result, pixelScale, pixelBias);
947
948 if (!isOk)
949 log << TestLog::Message << "Image comparison failed, threshold = " << threshold << TestLog::EndMessage;
950
951 log << TestLog::ImageSet(imageSetName, imageSetDesc)
952 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
953 << TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
954 << TestLog::Image("ErrorMask", "Error mask", errorMask)
955 << TestLog::EndImageSet;
956 }
957 else if (logMode == COMPARE_LOG_RESULT)
958 {
959 if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
960 computePixelScaleBias(result, pixelScale, pixelBias);
961
962 log << TestLog::ImageSet(imageSetName, imageSetDesc)
963 << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
964 << TestLog::EndImageSet;
965 }
966
967 return isOk;
968 }
969
970 } // tcu
971