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