/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Image comparison utilities.
 *//*--------------------------------------------------------------------*/

#include "tcuImageCompare.hpp"
#include "tcuSurface.hpp"
#include "tcuFuzzyImageCompare.hpp"
#include "tcuBilinearImageCompare.hpp"
#include "tcuTestLog.hpp"
#include "tcuVector.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuRGBA.hpp"
#include "tcuTexture.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuFloat.hpp"

#include <string.h>

namespace tcu
{

namespace
{

void computeScaleAndBias(const ConstPixelBufferAccess &reference, const ConstPixelBufferAccess &result,
                         tcu::Vec4 &scale, tcu::Vec4 &bias)
{
    Vec4 minVal;
    Vec4 maxVal;
    const float eps = 0.0001f;

    {
        Vec4 refMin;
        Vec4 refMax;
        estimatePixelValueRange(reference, refMin, refMax);

        minVal = refMin;
        maxVal = refMax;
    }

    {
        Vec4 resMin;
        Vec4 resMax;

        estimatePixelValueRange(result, resMin, resMax);

        minVal[0] = de::min(minVal[0], resMin[0]);
        minVal[1] = de::min(minVal[1], resMin[1]);
        minVal[2] = de::min(minVal[2], resMin[2]);
        minVal[3] = de::min(minVal[3], resMin[3]);

        maxVal[0] = de::max(maxVal[0], resMax[0]);
        maxVal[1] = de::max(maxVal[1], resMax[1]);
        maxVal[2] = de::max(maxVal[2], resMax[2]);
        maxVal[3] = de::max(maxVal[3], resMax[3]);
    }

    for (int c = 0; c < 4; c++)
    {
        if (maxVal[c] - minVal[c] < eps)
        {
            scale[c] = (maxVal[c] < eps) ? 1.0f : (1.0f / maxVal[c]);
            bias[c]  = (c == 3) ? (1.0f - maxVal[c] * scale[c]) : (0.0f - minVal[c] * scale[c]);
        }
        else
        {
            scale[c] = 1.0f / (maxVal[c] - minVal[c]);
            bias[c]  = 0.0f - minVal[c] * scale[c];
        }
    }
}

static int findNumPositionDeviationFailingPixels(const PixelBufferAccess &errorMask,
                                                 const ConstPixelBufferAccess &reference,
                                                 const ConstPixelBufferAccess &result, const UVec4 &threshold,
                                                 const tcu::IVec3 &maxPositionDeviation,
                                                 bool acceptOutOfBoundsAsAnyValue)
{
    const tcu::IVec4 okColor(0, 255, 0, 255);
    const tcu::IVec4 errorColor(255, 0, 0, 255);
    const int width      = reference.getWidth();
    const int height     = reference.getHeight();
    const int depth      = reference.getDepth();
    int numFailingPixels = 0;

    // Accept pixels "sampling" over the image bounds pixels since "taps" could be anything
    const int beginX = (acceptOutOfBoundsAsAnyValue) ? (maxPositionDeviation.x()) : (0);
    const int beginY = (acceptOutOfBoundsAsAnyValue) ? (maxPositionDeviation.y()) : (0);
    const int beginZ = (acceptOutOfBoundsAsAnyValue) ? (maxPositionDeviation.z()) : (0);
    const int endX   = (acceptOutOfBoundsAsAnyValue) ? (width - maxPositionDeviation.x()) : (width);
    const int endY   = (acceptOutOfBoundsAsAnyValue) ? (height - maxPositionDeviation.y()) : (height);
    const int endZ   = (acceptOutOfBoundsAsAnyValue) ? (depth - maxPositionDeviation.z()) : (depth);

    TCU_CHECK_INTERNAL(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth);
    DE_ASSERT(endX > 0 && endY > 0 && endZ > 0); // most likely a bug

    tcu::clear(errorMask, okColor);

    for (int z = beginZ; z < endZ; z++)
    {
        for (int y = beginY; y < endY; y++)
        {
            for (int x = beginX; x < endX; x++)
            {
                const IVec4 refPix = reference.getPixelInt(x, y, z);
                const IVec4 cmpPix = result.getPixelInt(x, y, z);

                // Exact match
                {
                    const UVec4 diff = abs(refPix - cmpPix).cast<uint32_t>();
                    const bool isOk  = boolAll(lessThanEqual(diff, threshold));

                    if (isOk)
                        continue;
                }

                // Find matching pixels for both result and reference pixel

                {
                    bool pixelFoundForReference = false;

                    // Find deviated result pixel for reference

                    for (int sz = de::max(0, z - maxPositionDeviation.z());
                         sz <= de::min(depth - 1, z + maxPositionDeviation.z()) && !pixelFoundForReference; ++sz)
                        for (int sy = de::max(0, y - maxPositionDeviation.y());
                             sy <= de::min(height - 1, y + maxPositionDeviation.y()) && !pixelFoundForReference; ++sy)
                            for (int sx = de::max(0, x - maxPositionDeviation.x());
                                 sx <= de::min(width - 1, x + maxPositionDeviation.x()) && !pixelFoundForReference;
                                 ++sx)
                            {
                                const IVec4 deviatedCmpPix = result.getPixelInt(sx, sy, sz);
                                const UVec4 diff           = abs(refPix - deviatedCmpPix).cast<uint32_t>();
                                const bool isOk            = boolAll(lessThanEqual(diff, threshold));

                                pixelFoundForReference = isOk;
                            }

                    if (!pixelFoundForReference)
                    {
                        errorMask.setPixel(errorColor, x, y, z);
                        ++numFailingPixels;
                        continue;
                    }
                }
                {
                    bool pixelFoundForResult = false;

                    // Find deviated reference pixel for result

                    for (int sz = de::max(0, z - maxPositionDeviation.z());
                         sz <= de::min(depth - 1, z + maxPositionDeviation.z()) && !pixelFoundForResult; ++sz)
                        for (int sy = de::max(0, y - maxPositionDeviation.y());
                             sy <= de::min(height - 1, y + maxPositionDeviation.y()) && !pixelFoundForResult; ++sy)
                            for (int sx = de::max(0, x - maxPositionDeviation.x());
                                 sx <= de::min(width - 1, x + maxPositionDeviation.x()) && !pixelFoundForResult; ++sx)
                            {
                                const IVec4 deviatedRefPix = reference.getPixelInt(sx, sy, sz);
                                const UVec4 diff           = abs(cmpPix - deviatedRefPix).cast<uint32_t>();
                                const bool isOk            = boolAll(lessThanEqual(diff, threshold));

                                pixelFoundForResult = isOk;
                            }

                    if (!pixelFoundForResult)
                    {
                        errorMask.setPixel(errorColor, x, y, z);
                        ++numFailingPixels;
                        continue;
                    }
                }
            }
        }
    }

    return numFailingPixels;
}

} // namespace

/*--------------------------------------------------------------------*//*!
 * \brief Fuzzy image comparison
 *
 * This image comparison is designed for comparing images rendered by 3D
 * graphics APIs such as OpenGL. The comparison allows small local differences
 * and compensates for aliasing.
 *
 * The algorithm first performs light blurring on both images and then
 * does per-pixel analysis. Pixels are compared to 3x3 bilinear surface
 * defined by adjecent pixels. This compensates for both 1-pixel deviations
 * in geometry and aliasing in texture data.
 *
 * Error metric is computed based on the differences. On valid images the
 * metric is usually <0.01. Thus good threshold values are in range 0.02 to
 * 0.05.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \note                Currently supports only UNORM_INT8 formats
 * \param log            Test log for results
 * \param imageSetName    Name for image set when logging results
 * \param imageSetDesc    Description for image set
 * \param reference        Reference image
 * \param result        Result image
 * \param threshold        Error metric threshold (good values are 0.02-0.05)
 * \param logMode        Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool fuzzyCompare(TestLog &log, const char *imageSetName, const char *imageSetDesc,
                  const ConstPixelBufferAccess &reference, const ConstPixelBufferAccess &result, float threshold,
                  CompareLogMode logMode)
{
    FuzzyCompareParams params; // Use defaults.
    TextureLevel errorMask(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), reference.getWidth(),
                           reference.getHeight());
    float difference = fuzzyCompare(params, reference, result, errorMask.getAccess());
    bool isOk        = difference <= threshold;
    Vec4 pixelBias(0.0f, 0.0f, 0.0f, 0.0f);
    Vec4 pixelScale(1.0f, 1.0f, 1.0f, 1.0f);

    if (!isOk || logMode == COMPARE_LOG_EVERYTHING)
    {
        // Generate more accurate error mask.
        params.maxSampleSkip = 0;
        fuzzyCompare(params, reference, result, errorMask.getAccess());

        if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8) &&
            reference.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
            computeScaleAndBias(reference, result, pixelScale, pixelBias);

        if (!isOk)
            log << TestLog::Message << "Image comparison failed: difference = " << difference
                << ", threshold = " << threshold << TestLog::EndMessage;

        log << TestLog::ImageSet(imageSetName, imageSetDesc)
            << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
            << TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
            << TestLog::Image("ErrorMask", "Error mask", errorMask) << TestLog::EndImageSet;
    }
    else if (logMode == COMPARE_LOG_RESULT)
    {
        if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
            computePixelScaleBias(result, pixelScale, pixelBias);

        log << TestLog::ImageSet(imageSetName, imageSetDesc)
            << TestLog::Image("Result", "Result", result, pixelScale, pixelBias) << TestLog::EndImageSet;
    }

    return isOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Fuzzy image comparison
 *
 * This image comparison is designed for comparing images rendered by 3D
 * graphics APIs such as OpenGL. The comparison allows small local differences
 * and compensates for aliasing.
 *
 * The algorithm first performs light blurring on both images and then
 * does per-pixel analysis. Pixels are compared to 3x3 bilinear surface
 * defined by adjecent pixels. This compensates for both 1-pixel deviations
 * in geometry and aliasing in texture data.
 *
 * Error metric is computed based on the differences. On valid images the
 * metric is usually <0.01. Thus good threshold values are in range 0.02 to
 * 0.05.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \note                Currently supports only UNORM_INT8 formats
 * \param log            Test log for results
 * \param imageSetName    Name for image set when logging results
 * \param imageSetDesc    Description for image set
 * \param reference        Reference image
 * \param result        Result image
 * \param threshold        Error metric threshold (good values are 0.02-0.05)
 * \param logMode        Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool fuzzyCompare(TestLog &log, const char *imageSetName, const char *imageSetDesc, const Surface &reference,
                  const Surface &result, float threshold, CompareLogMode logMode)
{
    return fuzzyCompare(log, imageSetName, imageSetDesc, reference.getAccess(), result.getAccess(), threshold, logMode);
}

static int64_t computeSquaredDiffSum(const ConstPixelBufferAccess &ref, const ConstPixelBufferAccess &cmp,
                                     const PixelBufferAccess &diffMask, int diffFactor)
{
    TCU_CHECK_INTERNAL(ref.getFormat().type == TextureFormat::UNORM_INT8 &&
                       cmp.getFormat().type == TextureFormat::UNORM_INT8);
    DE_ASSERT(ref.getWidth() == cmp.getWidth() && ref.getWidth() == diffMask.getWidth());
    DE_ASSERT(ref.getHeight() == cmp.getHeight() && ref.getHeight() == diffMask.getHeight());

    int64_t diffSum = 0;

    for (int y = 0; y < cmp.getHeight(); y++)
    {
        for (int x = 0; x < cmp.getWidth(); x++)
        {
            IVec4 a    = ref.getPixelInt(x, y);
            IVec4 b    = cmp.getPixelInt(x, y);
            IVec4 diff = abs(a - b);
            int sum    = diff.x() + diff.y() + diff.z() + diff.w();
            int sqSum  = diff.x() * diff.x() + diff.y() * diff.y() + diff.z() * diff.z() + diff.w() * diff.w();

            diffMask.setPixel(
                tcu::RGBA(deClamp32(sum * diffFactor, 0, 255), deClamp32(255 - sum * diffFactor, 0, 255), 0, 255)
                    .toVec(),
                x, y);

            diffSum += (int64_t)sqSum;
        }
    }

    return diffSum;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel difference accuracy metric
 *
 * Computes accuracy metric using per-pixel differences between reference
 * and result images.
 *
 * \note                    Supports only integer- and fixed-point formats
 * \param log                Test log for results
 * \param imageSetName        Name for image set when logging results
 * \param imageSetDesc        Description for image set
 * \param reference            Reference image
 * \param result            Result image
 * \param bestScoreDiff        Scaling factor
 * \param worstScoreDiff    Scaling factor
 * \param logMode            Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
int measurePixelDiffAccuracy(TestLog &log, const char *imageSetName, const char *imageSetDesc,
                             const ConstPixelBufferAccess &reference, const ConstPixelBufferAccess &result,
                             int bestScoreDiff, int worstScoreDiff, CompareLogMode logMode)
{
    TextureLevel diffMask(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), reference.getWidth(),
                          reference.getHeight());
    int diffFactor     = 8;
    int64_t squaredSum = computeSquaredDiffSum(reference, result, diffMask.getAccess(), diffFactor);
    float sum          = deFloatSqrt((float)squaredSum);
    int score          = deClamp32(
        deFloorFloatToInt32(
            100.0f - (de::max(sum - (float)bestScoreDiff, 0.0f) / (float)(worstScoreDiff - bestScoreDiff)) * 100.0f),
        0, 100);
    const int failThreshold = 10;
    Vec4 pixelBias(0.0f, 0.0f, 0.0f, 0.0f);
    Vec4 pixelScale(1.0f, 1.0f, 1.0f, 1.0f);

    if (logMode == COMPARE_LOG_EVERYTHING || score <= failThreshold)
    {
        if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8) &&
            reference.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
            computeScaleAndBias(reference, result, pixelScale, pixelBias);

        log << TestLog::ImageSet(imageSetName, imageSetDesc)
            << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
            << TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
            << TestLog::Image("DiffMask", "Difference", diffMask) << TestLog::EndImageSet;
    }
    else if (logMode == COMPARE_LOG_RESULT)
    {
        if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
            computePixelScaleBias(result, pixelScale, pixelBias);

        log << TestLog::ImageSet(imageSetName, imageSetDesc)
            << TestLog::Image("Result", "Result", result, pixelScale, pixelBias) << TestLog::EndImageSet;
    }

    if (logMode != COMPARE_LOG_ON_ERROR || score <= failThreshold)
        log << TestLog::Integer("DiffSum", "Squared difference sum", "", QP_KEY_TAG_NONE, squaredSum)
            << TestLog::Integer("Score", "Score", "", QP_KEY_TAG_QUALITY, score);

    return score;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel difference accuracy metric
 *
 * Computes accuracy metric using per-pixel differences between reference
 * and result images.
 *
 * \note                    Supports only integer- and fixed-point formats
 * \param log                Test log for results
 * \param imageSetName        Name for image set when logging results
 * \param imageSetDesc        Description for image set
 * \param reference            Reference image
 * \param result            Result image
 * \param bestScoreDiff        Scaling factor
 * \param worstScoreDiff    Scaling factor
 * \param logMode            Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
int measurePixelDiffAccuracy(TestLog &log, const char *imageSetName, const char *imageSetDesc, const Surface &reference,
                             const Surface &result, int bestScoreDiff, int worstScoreDiff, CompareLogMode logMode)
{
    return measurePixelDiffAccuracy(log, imageSetName, imageSetDesc, reference.getAccess(), result.getAccess(),
                                    bestScoreDiff, worstScoreDiff, logMode);
}

/*--------------------------------------------------------------------*//*!
 * Returns the index of float in a float space without denormals
 * so that:
 * 1) f(0.0) = 0
 * 2) f(-0.0) = 0
 * 3) f(b) = f(a) + 1  <==>  b = nextAfter(a)
 *
 * See computeFloatFlushRelaxedULPDiff for details
 *//*--------------------------------------------------------------------*/
static int32_t getPositionOfIEEEFloatWithoutDenormals(float x)
{
    DE_ASSERT(!deIsNaN(x)); // not sane

    if (x == 0.0f)
        return 0;
    else if (x < 0.0f)
        return -getPositionOfIEEEFloatWithoutDenormals(-x);
    else
    {
        DE_ASSERT(x > 0.0f);

        const tcu::Float32 f(x);

        if (f.isDenorm())
        {
            // Denorms are flushed to zero
            return 0;
        }
        else
        {
            // sign is 0, and it's a normal number. Natural position is its bit
            // pattern but since we've collapsed the denorms, we must remove
            // the gap here too to keep the float enumeration continuous.
            //
            // Denormals occupy one exponent pattern. Removing one from
            // exponent should to the trick. Add one since the removed range
            // contained one representable value, 0.
            return (int32_t)(f.bits() - (1u << 23u) + 1u);
        }
    }
}

static uint32_t computeFloatFlushRelaxedULPDiff(float a, float b)
{
    if (deIsNaN(a) && deIsNaN(b))
        return 0;
    else if (deIsNaN(a) || deIsNaN(b))
    {
        return 0xFFFFFFFFu;
    }
    else
    {
        // Using the "definition 5" in Muller, Jean-Michel. "On the definition of ulp (x)" (2005)
        // assuming a floating point space is IEEE single precision floating point space without
        // denormals (and signed zeros).
        const int32_t aIndex = getPositionOfIEEEFloatWithoutDenormals(a);
        const int32_t bIndex = getPositionOfIEEEFloatWithoutDenormals(b);
        return (uint32_t)de::abs(aIndex - bIndex);
    }
}

static tcu::UVec4 computeFlushRelaxedULPDiff(const tcu::Vec4 &a, const tcu::Vec4 &b)
{
    return tcu::UVec4(computeFloatFlushRelaxedULPDiff(a.x(), b.x()), computeFloatFlushRelaxedULPDiff(a.y(), b.y()),
                      computeFloatFlushRelaxedULPDiff(a.z(), b.z()), computeFloatFlushRelaxedULPDiff(a.w(), b.w()));
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel threshold-based comparison
 *
 * This compare computes per-pixel differences between result and reference
 * image. Comparison fails if any pixels exceed the given threshold value.
 *
 * This comparison uses ULP (units in last place) metric for computing the
 * difference between floating-point values and thus this function can
 * be used only for comparing floating-point texture data. In ULP calculation
 * the denormal numbers are allowed to be flushed to zero.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \param log            Test log for results
 * \param imageSetName    Name for image set when logging results
 * \param imageSetDesc    Description for image set
 * \param reference        Reference image
 * \param result        Result image
 * \param threshold        Maximum allowed difference
 * \param logMode        Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool floatUlpThresholdCompare(TestLog &log, const char *imageSetName, const char *imageSetDesc,
                              const ConstPixelBufferAccess &reference, const ConstPixelBufferAccess &result,
                              const UVec4 &threshold, CompareLogMode logMode)
{
    int width  = reference.getWidth();
    int height = reference.getHeight();
    int depth  = reference.getDepth();
    TextureLevel errorMaskStorage(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
    PixelBufferAccess errorMask = errorMaskStorage.getAccess();
    UVec4 maxDiff(0, 0, 0, 0);
    Vec4 pixelBias(0.0f, 0.0f, 0.0f, 0.0f);
    Vec4 pixelScale(1.0f, 1.0f, 1.0f, 1.0f);

    TCU_CHECK(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth);

    for (int z = 0; z < depth; z++)
    {
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                const Vec4 refPix = reference.getPixel(x, y, z);
                const Vec4 cmpPix = result.getPixel(x, y, z);
                const UVec4 diff  = computeFlushRelaxedULPDiff(refPix, cmpPix);
                const bool isOk   = boolAll(lessThanEqual(diff, threshold));

                maxDiff = max(maxDiff, diff);

                errorMask.setPixel(isOk ? Vec4(0.0f, 1.0f, 0.0f, 1.0f) : Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
            }
        }
    }

    bool compareOk = boolAll(lessThanEqual(maxDiff, threshold));

    if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
    {
        // All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
        if (tcu::getTextureChannelClass(reference.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
            tcu::getTextureChannelClass(result.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
        {
            computeScaleAndBias(reference, result, pixelScale, pixelBias);
            log << TestLog::Message << "Result and reference images are normalized with formula p * " << pixelScale
                << " + " << pixelBias << TestLog::EndMessage;
        }

        if (!compareOk)
            log << TestLog::Message << "Image comparison failed: max difference = " << maxDiff
                << ", threshold = " << threshold << TestLog::EndMessage;

        log << TestLog::ImageSet(imageSetName, imageSetDesc)
            << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
            << TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
            << TestLog::Image("ErrorMask", "Error mask", errorMask) << TestLog::EndImageSet;
    }
    else if (logMode == COMPARE_LOG_RESULT)
    {
        if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
            computePixelScaleBias(result, pixelScale, pixelBias);

        log << TestLog::ImageSet(imageSetName, imageSetDesc)
            << TestLog::Image("Result", "Result", result, pixelScale, pixelBias) << TestLog::EndImageSet;
    }

    return compareOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel threshold-based comparison
 *
 * This compare computes per-pixel differences between result and reference
 * image. Comparison fails if any pixels exceed the given threshold value.
 *
 * This comparison can be used for floating-point and fixed-point formats.
 * Difference is computed in floating-point space.
 *
 * On failure an error image is generated that shows where the failing
 * pixels are.
 *
 * \param log            Test log for results
 * \param imageSetName    Name for image set when logging results
 * \param imageSetDesc    Description for image set
 * \param reference        Reference image
 * \param result        Result image
 * \param threshold        Maximum allowed difference
 * \param logMode        Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool floatThresholdCompare(TestLog &log, const char *imageSetName, const char *imageSetDesc,
                           const ConstPixelBufferAccess &reference, const ConstPixelBufferAccess &result,
                           const Vec4 &threshold, CompareLogMode logMode)
{
    int width  = reference.getWidth();
    int height = reference.getHeight();
    int depth  = reference.getDepth();
    TextureLevel errorMaskStorage(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
    PixelBufferAccess errorMask = errorMaskStorage.getAccess();
    Vec4 maxDiff(0.0f, 0.0f, 0.0f, 0.0f);
    Vec4 pixelBias(0.0f, 0.0f, 0.0f, 0.0f);
    Vec4 pixelScale(1.0f, 1.0f, 1.0f, 1.0f);

    TCU_CHECK_INTERNAL(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth);

    for (int z = 0; z < depth; z++)
    {
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                Vec4 refPix = reference.getPixel(x, y, z);
                Vec4 cmpPix = result.getPixel(x, y, z);

                Vec4 diff = abs(refPix - cmpPix);
                bool isOk = boolAll(lessThanEqual(diff, threshold));

                maxDiff = max(maxDiff, diff);

                errorMask.setPixel(isOk ? Vec4(0.0f, 1.0f, 0.0f, 1.0f) : Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
            }
        }
    }

    bool compareOk = boolAll(lessThanEqual(maxDiff, threshold));

    if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
    {
        // All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
        if (tcu::getTextureChannelClass(reference.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
            tcu::getTextureChannelClass(result.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
        {
            computeScaleAndBias(reference, result, pixelScale, pixelBias);
            log << TestLog::Message << "Result and reference images are normalized with formula p * " << pixelScale
                << " + " << pixelBias << TestLog::EndMessage;
        }

        if (!compareOk)
            log << TestLog::Message << "Image comparison failed: max difference = " << maxDiff
                << ", threshold = " << threshold << TestLog::EndMessage;

        log << TestLog::ImageSet(imageSetName, imageSetDesc)
            << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
            << TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
            << TestLog::Image("ErrorMask", "Error mask", errorMask) << TestLog::EndImageSet;
    }
    else if (logMode == COMPARE_LOG_RESULT)
    {
        if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
            computePixelScaleBias(result, pixelScale, pixelBias);

        log << TestLog::ImageSet(imageSetName, imageSetDesc)
            << TestLog::Image("Result", "Result", result, pixelScale, pixelBias) << TestLog::EndImageSet;
    }

    return compareOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel threshold-based comparison
 *
 * This compare computes per-pixel differences between result and reference
 * color. Comparison fails if any pixels exceed the given threshold value.
 *
 * This comparison can be used for floating-point and fixed-point formats.
 * Difference is computed in floating-point space.
 *
 * On failure an error image is generated that shows where the failing
 * pixels are.
 *
 * \param log            Test log for results
 * \param imageSetName    Name for image set when logging results
 * \param imageSetDesc    Description for image set
 * \param reference        Reference color
 * \param result        Result image
 * \param threshold        Maximum allowed difference
 * \param logMode        Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool floatThresholdCompare(TestLog &log, const char *imageSetName, const char *imageSetDesc, const Vec4 &reference,
                           const ConstPixelBufferAccess &result, const Vec4 &threshold, CompareLogMode logMode)
{
    const int width  = result.getWidth();
    const int height = result.getHeight();
    const int depth  = result.getDepth();

    TextureLevel errorMaskStorage(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
    PixelBufferAccess errorMask = errorMaskStorage.getAccess();
    Vec4 maxDiff(0.0f, 0.0f, 0.0f, 0.0f);
    Vec4 pixelBias(0.0f, 0.0f, 0.0f, 0.0f);
    Vec4 pixelScale(1.0f, 1.0f, 1.0f, 1.0f);

    for (int z = 0; z < depth; z++)
    {
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                const Vec4 cmpPix = result.getPixel(x, y, z);
                const Vec4 diff   = abs(reference - cmpPix);
                const bool isOk   = boolAll(lessThanEqual(diff, threshold));

                maxDiff = max(maxDiff, diff);

                errorMask.setPixel(isOk ? Vec4(0.0f, 1.0f, 0.0f, 1.0f) : Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
            }
        }
    }

    bool compareOk = boolAll(lessThanEqual(maxDiff, threshold));

    if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
    {
        // All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
        if (tcu::getTextureChannelClass(result.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
        {
            computeScaleAndBias(result, result, pixelScale, pixelBias);
            log << TestLog::Message << "Result image is normalized with formula p * " << pixelScale << " + "
                << pixelBias << TestLog::EndMessage;
        }

        if (!compareOk)
            log << TestLog::Message << "Image comparison failed: max difference = " << maxDiff
                << ", threshold = " << threshold << ", reference = " << reference << TestLog::EndMessage;

        log << TestLog::ImageSet(imageSetName, imageSetDesc)
            << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
            << TestLog::Image("ErrorMask", "Error mask", errorMask) << TestLog::EndImageSet;
    }
    else if (logMode == COMPARE_LOG_RESULT)
    {
        if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
            computePixelScaleBias(result, pixelScale, pixelBias);

        log << TestLog::ImageSet(imageSetName, imageSetDesc)
            << TestLog::Image("Result", "Result", result, pixelScale, pixelBias) << TestLog::EndImageSet;
    }

    return compareOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel threshold-based comparison
 *
 * This compare computes per-pixel differences between result and reference
 * image. Comparison fails if any pixels exceed the given threshold value.
 *
 * This comparison can be used for integer- and fixed-point texture formats.
 * Difference is computed in integer space.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \param log            Test log for results
 * \param imageSetName    Name for image set when logging results
 * \param imageSetDesc    Description for image set
 * \param reference        Reference image
 * \param result        Result image
 * \param threshold        Maximum allowed difference
 * \param logMode        Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool intThresholdCompare(TestLog &log, const char *imageSetName, const char *imageSetDesc,
                         const ConstPixelBufferAccess &reference, const ConstPixelBufferAccess &result,
                         const UVec4 &threshold, CompareLogMode logMode)
{
    int width  = reference.getWidth();
    int height = reference.getHeight();
    int depth  = reference.getDepth();
    TextureLevel errorMaskStorage(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
    PixelBufferAccess errorMask = errorMaskStorage.getAccess();
    UVec4 maxDiff(0, 0, 0, 0);
    Vec4 pixelBias(0.0f, 0.0f, 0.0f, 0.0f);
    Vec4 pixelScale(1.0f, 1.0f, 1.0f, 1.0f);

    TCU_CHECK_INTERNAL(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth);

    for (int z = 0; z < depth; z++)
    {
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                IVec4 refPix = reference.getPixelInt(x, y, z);
                IVec4 cmpPix = result.getPixelInt(x, y, z);

                UVec4 diff = abs(refPix - cmpPix).cast<uint32_t>();
                bool isOk  = boolAll(lessThanEqual(diff, threshold));

                maxDiff = max(maxDiff, diff);

                errorMask.setPixel(isOk ? IVec4(0, 0xff, 0, 0xff) : IVec4(0xff, 0, 0, 0xff), x, y, z);
            }
        }
    }

    bool compareOk = boolAll(lessThanEqual(maxDiff, threshold));

    if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
    {
        // All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
        if (tcu::getTextureChannelClass(reference.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
            tcu::getTextureChannelClass(result.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
        {
            computeScaleAndBias(reference, result, pixelScale, pixelBias);
            log << TestLog::Message << "Result and reference images are normalized with formula p * " << pixelScale
                << " + " << pixelBias << TestLog::EndMessage;
        }

        if (!compareOk)
            log << TestLog::Message << "Image comparison failed: max difference = " << maxDiff
                << ", threshold = " << threshold << TestLog::EndMessage;

        log << TestLog::ImageSet(imageSetName, imageSetDesc)
            << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
            << TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
            << TestLog::Image("ErrorMask", "Error mask", errorMask) << TestLog::EndImageSet;
    }
    else if (logMode == COMPARE_LOG_RESULT)
    {
        if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
            computePixelScaleBias(result, pixelScale, pixelBias);

        log << TestLog::ImageSet(imageSetName, imageSetDesc)
            << TestLog::Image("Result", "Result", result, pixelScale, pixelBias) << TestLog::EndImageSet;
    }

    return compareOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel depth/stencil threshold-based comparison
 *
 * This compare computes per-pixel differences between result and reference
 * image. Comparison fails if any pixels exceed the given threshold value.
 *
 * This comparison can be used for depth and depth/stencil images.
 * Difference is computed in integer space.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \param log            Test log for results
 * \param imageSetName    Name for image set when logging results
 * \param imageSetDesc    Description for image set
 * \param reference        Reference image
 * \param result        Result image
 * \param threshold        Maximum allowed depth difference (stencil must be exact)
 * \param logMode        Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool dsThresholdCompare(TestLog &log, const char *imageSetName, const char *imageSetDesc,
                        const ConstPixelBufferAccess &reference, const ConstPixelBufferAccess &result,
                        const float threshold, CompareLogMode logMode)
{
    int width  = reference.getWidth();
    int height = reference.getHeight();
    int depth  = reference.getDepth();
    TextureLevel errorMaskStorage(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
    PixelBufferAccess errorMask = errorMaskStorage.getAccess();
    float maxDiff               = 0.0;
    bool allStencilOk           = true;
    bool hasDepth               = tcu::hasDepthComponent(result.getFormat().order);
    bool hasStencil             = tcu::hasStencilComponent(result.getFormat().order);

    TCU_CHECK_INTERNAL(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth);

    for (int z = 0; z < depth; z++)
    {
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                bool isOk = true;

                if (hasDepth)
                {
                    float refDepth = reference.getPixDepth(x, y, z);
                    float cmpDepth = result.getPixDepth(x, y, z);

                    float diff = refDepth - cmpDepth;
                    isOk       = diff <= threshold;
                    maxDiff    = (float)deMax(maxDiff, diff);
                }

                if (hasStencil)
                {
                    uint8_t refStencil = (uint8_t)reference.getPixStencil(x, y, z);
                    uint8_t cmpStencil = (uint8_t)result.getPixStencil(x, y, z);

                    bool isStencilOk = (refStencil == cmpStencil);
                    allStencilOk     = allStencilOk && isStencilOk;
                    isOk             = isOk && isStencilOk;
                }

                errorMask.setPixel(isOk ? IVec4(0, 0xff, 0, 0xff) : IVec4(0xff, 0, 0, 0xff), x, y, z);
            }
        }
    }

    bool compareOk = (maxDiff <= threshold) && allStencilOk;

    if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
    {
        if (!compareOk)
        {
            if (maxDiff > threshold)
                log << TestLog::Message << "Depth comparison failed: max difference = " << maxDiff
                    << ", threshold = " << threshold << TestLog::EndMessage;
            if (!allStencilOk)
                log << TestLog::Message << "Stencil comparison failed" << TestLog::EndMessage;
        }

        log << TestLog::ImageSet(imageSetName, imageSetDesc)
            // TODO: Convert depth/stencil buffers into separate depth & stencil for logging?
            //            << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
            //            << TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
            << TestLog::Image("ErrorMask", "Error mask", errorMask) << TestLog::EndImageSet;
    }
    else if (logMode == COMPARE_LOG_RESULT)
    {
#if 0
        if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
            computePixelScaleBias(result, pixelScale, pixelBias);

        log << TestLog::ImageSet(imageSetName, imageSetDesc)
            << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
            << TestLog::EndImageSet;
#endif
    }

    return compareOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel threshold-based deviation-ignoring comparison
 *
 * This compare computes per-pixel differences between result and reference
 * image. Comparison fails if there is no pixel matching the given threshold
 * value in the search volume.
 *
 * If the search volume contains out-of-bounds pixels, comparison can be set
 * to either ignore these pixels in search or to accept any pixel that has
 * out-of-bounds pixels in its search volume.
 *
 * This comparison can be used for integer- and fixed-point texture formats.
 * Difference is computed in integer space.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \param log                            Test log for results
 * \param imageSetName                    Name for image set when logging results
 * \param imageSetDesc                    Description for image set
 * \param reference                        Reference image
 * \param result                        Result image
 * \param threshold                        Maximum allowed difference
 * \param maxPositionDeviation            Maximum allowed distance in the search
 *                                        volume.
 * \param acceptOutOfBoundsAsAnyValue    Accept any pixel in the boundary region
 * \param logMode                        Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
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)
{
    const int width  = reference.getWidth();
    const int height = reference.getHeight();
    const int depth  = reference.getDepth();
    TextureLevel errorMaskStorage(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
    PixelBufferAccess errorMask = errorMaskStorage.getAccess();
    const int numFailingPixels  = findNumPositionDeviationFailingPixels(
        errorMask, reference, result, threshold, maxPositionDeviation, acceptOutOfBoundsAsAnyValue);
    const bool compareOk = numFailingPixels == 0;
    Vec4 pixelBias(0.0f, 0.0f, 0.0f, 0.0f);
    Vec4 pixelScale(1.0f, 1.0f, 1.0f, 1.0f);

    if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
    {
        // All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
        if (tcu::getTextureChannelClass(reference.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
            tcu::getTextureChannelClass(result.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
        {
            computeScaleAndBias(reference, result, pixelScale, pixelBias);
            log << TestLog::Message << "Result and reference images are normalized with formula p * " << pixelScale
                << " + " << pixelBias << TestLog::EndMessage;
        }

        if (!compareOk)
            log << TestLog::Message << "Image comparison failed:\n"
                << "\tallowed position deviation = " << maxPositionDeviation << "\n"
                << "\tcolor threshold = " << threshold << TestLog::EndMessage;

        log << TestLog::ImageSet(imageSetName, imageSetDesc)
            << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
            << TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
            << TestLog::Image("ErrorMask", "Error mask", errorMask) << TestLog::EndImageSet;
    }
    else if (logMode == COMPARE_LOG_RESULT)
    {
        if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
            computePixelScaleBias(result, pixelScale, pixelBias);

        log << TestLog::ImageSet(imageSetName, imageSetDesc)
            << TestLog::Image("Result", "Result", result, pixelScale, pixelBias) << TestLog::EndImageSet;
    }

    return compareOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel threshold-based deviation-ignoring comparison
 *
 * This compare computes per-pixel differences between result and reference
 * image. Pixel fails the test if there is no pixel matching the given
 * threshold value in the search volume. Comparison fails if the number of
 * failing pixels exceeds the given limit.
 *
 * If the search volume contains out-of-bounds pixels, comparison can be set
 * to either ignore these pixels in search or to accept any pixel that has
 * out-of-bounds pixels in its search volume.
 *
 * This comparison can be used for integer- and fixed-point texture formats.
 * Difference is computed in integer space.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \param log                            Test log for results
 * \param imageSetName                    Name for image set when logging results
 * \param imageSetDesc                    Description for image set
 * \param reference                        Reference image
 * \param result                        Result image
 * \param threshold                        Maximum allowed difference
 * \param maxPositionDeviation            Maximum allowed distance in the search
 *                                        volume.
 * \param acceptOutOfBoundsAsAnyValue    Accept any pixel in the boundary region
 * \param maxAllowedFailingPixels        Maximum number of failing pixels
 * \param logMode                        Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
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)
{
    const int width  = reference.getWidth();
    const int height = reference.getHeight();
    const int depth  = reference.getDepth();
    TextureLevel errorMaskStorage(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
    PixelBufferAccess errorMask = errorMaskStorage.getAccess();
    const int numFailingPixels  = findNumPositionDeviationFailingPixels(
        errorMask, reference, result, threshold, maxPositionDeviation, acceptOutOfBoundsAsAnyValue);
    const bool compareOk = numFailingPixels <= maxAllowedFailingPixels;
    Vec4 pixelBias(0.0f, 0.0f, 0.0f, 0.0f);
    Vec4 pixelScale(1.0f, 1.0f, 1.0f, 1.0f);

    if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
    {
        // All formats except normalized unsigned fixed point ones need remapping in order to fit into unorm channels in logged images.
        if (tcu::getTextureChannelClass(reference.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
            tcu::getTextureChannelClass(result.getFormat().type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
        {
            computeScaleAndBias(reference, result, pixelScale, pixelBias);
            log << TestLog::Message << "Result and reference images are normalized with formula p * " << pixelScale
                << " + " << pixelBias << TestLog::EndMessage;
        }

        if (!compareOk)
            log << TestLog::Message << "Image comparison failed:\n"
                << "\tallowed position deviation = " << maxPositionDeviation << "\n"
                << "\tcolor threshold = " << threshold << TestLog::EndMessage;
        log << TestLog::Message << "Number of failing pixels = " << numFailingPixels
            << ", max allowed = " << maxAllowedFailingPixels << TestLog::EndMessage;

        log << TestLog::ImageSet(imageSetName, imageSetDesc)
            << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
            << TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
            << TestLog::Image("ErrorMask", "Error mask", errorMask) << TestLog::EndImageSet;
    }
    else if (logMode == COMPARE_LOG_RESULT)
    {
        if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
            computePixelScaleBias(result, pixelScale, pixelBias);

        log << TestLog::ImageSet(imageSetName, imageSetDesc)
            << TestLog::Image("Result", "Result", result, pixelScale, pixelBias) << TestLog::EndImageSet;
    }

    return compareOk;
}

/*--------------------------------------------------------------------*//*!
 * \brief Per-pixel threshold-based comparison
 *
 * This compare computes per-pixel differences between result and reference
 * image. Comparison fails if any pixels exceed the given threshold value.
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \param log            Test log for results
 * \param imageSetName    Name for image set when logging results
 * \param imageSetDesc    Description for image set
 * \param reference        Reference image
 * \param result        Result image
 * \param threshold        Maximum allowed difference
 * \param logMode        Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool pixelThresholdCompare(TestLog &log, const char *imageSetName, const char *imageSetDesc, const Surface &reference,
                           const Surface &result, const RGBA &threshold, CompareLogMode logMode)
{
    return intThresholdCompare(log, imageSetName, imageSetDesc, reference.getAccess(), result.getAccess(),
                               threshold.toIVec().cast<uint32_t>(), logMode);
}

/*--------------------------------------------------------------------*//*!
 * \brief Bilinear image comparison
 *
 * \todo [pyry] Describe
 *
 * On failure error image is generated that shows where the failing pixels
 * are.
 *
 * \note                Currently supports only RGBA, UNORM_INT8 formats
 * \param log            Test log for results
 * \param imageSetName    Name for image set when logging results
 * \param imageSetDesc    Description for image set
 * \param reference        Reference image
 * \param result        Result image
 * \param threshold        Maximum local difference
 * \param logMode        Logging mode
 * \return true if comparison passes, false otherwise
 *//*--------------------------------------------------------------------*/
bool bilinearCompare(TestLog &log, const char *imageSetName, const char *imageSetDesc,
                     const ConstPixelBufferAccess &reference, const ConstPixelBufferAccess &result,
                     const RGBA threshold, CompareLogMode logMode)
{
    TextureLevel errorMask(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), reference.getWidth(),
                           reference.getHeight());
    bool isOk = bilinearCompare(reference, result, errorMask, threshold);
    Vec4 pixelBias(0.0f, 0.0f, 0.0f, 0.0f);
    Vec4 pixelScale(1.0f, 1.0f, 1.0f, 1.0f);

    if (!isOk || logMode == COMPARE_LOG_EVERYTHING)
    {
        if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8) &&
            reference.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
            computeScaleAndBias(reference, result, pixelScale, pixelBias);

        if (!isOk)
            log << TestLog::Message << "Image comparison failed, threshold = " << threshold << TestLog::EndMessage;

        log << TestLog::ImageSet(imageSetName, imageSetDesc)
            << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
            << TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
            << TestLog::Image("ErrorMask", "Error mask", errorMask) << TestLog::EndImageSet;
    }
    else if (logMode == COMPARE_LOG_RESULT)
    {
        if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
            computePixelScaleBias(result, pixelScale, pixelBias);

        log << TestLog::ImageSet(imageSetName, imageSetDesc)
            << TestLog::Image("Result", "Result", result, pixelScale, pixelBias) << TestLog::EndImageSet;
    }

    return isOk;
}

} // namespace tcu
