/*
 * Copyright 2026 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "tests/Test.h"

#include "include/core/SkColorType.h"
#include "include/gpu/graphite/Context.h"
#include "include/gpu/graphite/TextureInfo.h"
#include "include/private/SkTArray.h"
#include "src/core/SkColorSpaceXformSteps.h"
#include "src/core/SkFloatBits.h"
#include "src/core/SkHalf.h"
#include "src/core/SkImageInfoPriv.h"
#include "src/core/SkRasterPipeline.h"
#include "src/gpu/Swizzle.h"
#include "src/gpu/graphite/Caps.h"
#include "src/gpu/graphite/ContextPriv.h"
#include "src/gpu/graphite/TextureFormat.h"
#include "src/gpu/graphite/TextureFormatXferFn.h"
#include "src/gpu/graphite/TextureInfoPriv.h"
#include "tools/ToolUtils.h"

// Uncomment the SK_ABORT() to exit on first pixel mismatch to help debugging
#define STOP_ON_TRANSFER_FAILURE // SK_ABORT();

namespace skgpu::graphite {

// Types for defining color type and format behavior expectations
enum ChannelDataType {
    UNorm, Signed, Float, FNorm, sRGB, XR, Pad
};

struct Channel {
    char fName; // rgbayuv01 and G (for gray)
    int fBits;
    ChannelDataType fType;
};

struct ColorTypeExpectation {
    SkColorType fColorType;
    Swizzle fReadSwizzle;
    std::optional<Swizzle> fWriteSwizzle; // not set implies not renderable
};

struct FormatExpectation {
    TextureFormat fFormat;
    skia_private::TArray<Channel> fChannels;
    SkTextureCompressionType fCompressionType = SkTextureCompressionType::kNone;

    // Not set implies transfers are disabled; it is composed with a ColorTypeExpectation's
    // read or write swizzle to produce the expected readback/upload swizzle.
    std::optional<Swizzle> fXferSwizzle;
    // The first color type expectation is assumed to be the best fit.
    skia_private::TArray<ColorTypeExpectation> fCompatibleColorTypes;

    // All of the expectations for the fixed properties of a TextureFormat are derived from its
    // fChannels definition.
    bool isFloatingPoint() const { return this->hasType(Float) || this->hasType(FNorm); }
    bool hasDepth() const { return this->hasChannel('d'); }
    bool hasStencil() const { return this->hasChannel('s'); }
    bool hasDepthOrStencil() const { return this->hasDepth() || this->hasStencil(); }
    bool isMultiplanar() const {
        return this->hasChannel('y') && this->hasChannel('u') && this->hasChannel('v');
    }

    bool autoClamps() const {
        // Auto clamping is derived from the type of the channel with the most bits
        bool autoClamp = true;
        int maxBitSize = 0;
        for (const Channel& c : fChannels) {
            if (c.fBits > maxBitSize) {
                autoClamp = c.fType == UNorm || c.fType == sRGB;
                maxBitSize = c.fBits;
            }
        }
        return autoClamp;
    }

    int bytesPerBlock() const {
        if (fCompressionType != SkTextureCompressionType::kNone) {
            // At the moment, all supported compression types have the same bytes per block
            return 8;
        }

        int bitCount = 0;
        for (const Channel& c : fChannels) {
            bitCount += c.fBits;
        }
        return bitCount / 8;
    }

    uint32_t channelMask() const {
        uint32_t mask = 0;
        if (this->hasChannel('r') || this->hasChannel('y')) {
            mask |= kRed_SkColorChannelFlag;
        }
        if (this->hasChannel('g') || this->hasChannel('u')) {
            mask |= kGreen_SkColorChannelFlag;
        }
        if (this->hasChannel('b') || this->hasChannel('v')) {
            mask |= kBlue_SkColorChannelFlag;
        }
        if (this->hasChannel('a')) {
            mask |= kAlpha_SkColorChannelFlag;
        }
        // Other channels do not contribute to SkColorChannel mask
        return mask;
    }

private:
    bool hasChannel(char channel) const {
        for (const Channel& c : fChannels) {
            if (c.fName == channel) {
                return true;
            }
        }
        return false;
    }
    bool hasType(ChannelDataType type) const {
        for (const Channel& c : fChannels) {
            if (c.fType == type) {
                return true;
            }
        }
        return false;
    }
};

using PixelData = std::array<uint8_t, 16>; // The largest texel/pixel size is RGBA32F = 16 bytes

uint32_t channel_to_bits(const Channel& channel, float value) {
    switch (channel.fType) {
        case Pad:
            // Pad should only be used with 'x', which produces NaN in channel_to_float, so
            // replace `value` with the default 'x' bit pattern in gen_channel_values, and then
            // fall through to UNorm handling to adjust it to the right bit depth
            SkASSERT(channel.fName == 'x');
            value = 0b0101 / 15.f;
            [[fallthrough]];

        case sRGB:
            // sRGB data is stored in a non-linear gamma and automatically decodes to linear when
            // being sampled or rendered into. This means an SRGB_8888 image with a linear
            // SkColorSpace behaves like a regular 8888 image with an sRGB SkColorSpace. But
            // transfers between CPU and GPU assume the SkColorSpace is the same, so we need to
            // interpret the `v` as if it were an 8888 image with a linear SkColorSpace and map to
            // the sRGB encoding.
            if (channel.fType == sRGB) {
                value = skcms_TransferFunction_eval(skcms_sRGB_Inverse_TransferFunction(), value);
            }
            [[fallthrough]];

        case UNorm: {
            uint32_t denominator = channel.fBits == 32 ? ~0 : ((1 << channel.fBits) - 1);
            return (uint32_t) std::round(value * denominator);
        }

        case XR:
            // See SkRP_opts::store_1010102_xr
            SkASSERT(channel.fBits == 10);
            return std::min((uint32_t) std::round(value * 510 + 384), 1023u);

        case FNorm:
            // For simplicity fall through to Float, the Norm is just a hint about range
            [[fallthrough]];
        case Float:
            SkASSERT(channel.fBits == 16 || channel.fBits == 32);
            return channel.fBits == 16 ? (uint32_t) SkFloatToHalf(value) : SkFloat2Bits(value);

        case Signed:
            // This should only be used for 's' channels, which are already not reaching this code
            SK_ABORT("Should not be generating Signed values for pixel data");
    }
    SkUNREACHABLE;
}

float channel_to_float(const Channel& channel, uint32_t bits) {
    switch (channel.fType) {
        case sRGB: [[fallthrough]]; // first treat as unorm then apply gamma TF
        case UNorm: {
            uint32_t denominator = channel.fBits == 32 ? ~0 : ((1 << channel.fBits) - 1);
            float vf = bits * (1 / (float) denominator);
            if (channel.fType == sRGB) {
                vf = skcms_TransferFunction_eval(skcms_sRGB_TransferFunction(), vf);
            }
            return vf;
        }

        case XR:     return (bits - 384.f) * (1/510.f);

        case FNorm:  [[fallthrough]]; // Values are interpreted the same, values are in [0,1]
        case Float:  return channel.fBits == 16 ? SkHalfToFloat((SkHalf) bits) : SkBits2Float(bits);

        case Signed: [[fallthrough]];
        case Pad:    return SK_FloatNaN; // No floating point printing
    }
    SkUNREACHABLE;
}

char apply_swizzle_to_name(char dstName, const Swizzle& srcToDst) {
    switch (dstName) {
        case 'r': return srcToDst[0];
        case 'g': return srcToDst[1];
        case 'b': return srcToDst[2];
        case 'a': return srcToDst[3];
        default:  return dstName;
    }
}

// Generate a unique value for `channelName` by applying `srcToDst` to the source channels.
float gen_channel_value(char name,
                        const Swizzle& loadSrcSwizzle,
                        SkSpan<const Channel> srcChannels) {
    name = apply_swizzle_to_name(name, loadSrcSwizzle);

    // Try to look for an exact channel match, in which case we use the unique value corresponding
    // to that channel name.
    for (size_t c = 0; c < srcChannels.size(); ++c) {
        if (srcChannels[c].fName == name ||
            (srcChannels[c].fName == 'G' && (name == 'r' || name == 'g' || name == 'b'))) {
            uint32_t v;
            switch (srcChannels[c].fName) {
                case 'r': v = 0b0001; break;
                case 'g': v = 0b0010; break;
                case 'b': v = 0b0100; break;
                case 'a': v = 0b1010; break; // `A` must additionally fit into 2 bit channel formats
                case 'x': v = 0b0101; break;
                case '0': v = 0b0000; break;
                case '1': v = 0b1111; break;
                case 'G': v = 0b1100; break; // arbitrary starting Gray value
                default:
                    // NOTE: 'd', 's', 'y', 'u', 'v' are valid channel names, but the formats that
                    // have those should not be participating in the read/write transfer testing.
                    SK_ABORT("Bad source channel name for pixel data generation: %c", name);
            }
            // Route through the source channel's bit representation to account for rounding
            return channel_to_float(srcChannels[c], channel_to_bits(srcChannels[c], v / 15.f));
        }
    }

    // We didn't find an exact channel match, so we either use default values or apply gray handling
    switch (name) {
        // Trivial default values
        case 'x':                               return SK_FloatNaN;
        case 'r': case 'g': case 'b': case '0': return 0.f;
        case 'a': case '1':                     return 1.f;

        // Construct a gray value from r, g, and b values of the source
        case 'G': {
            float r = gen_channel_value('r', loadSrcSwizzle, srcChannels);
            float g = gen_channel_value('g', loadSrcSwizzle, srcChannels);
            float b = gen_channel_value('b', loadSrcSwizzle, srcChannels);

            // Since this is a linear sum, if we divided or multiplied by A after converting
            // through source's precision, we would arrive at the same value as if we applied
            // the premul/unpremul multiplication in gen_pixel_data applied to G
            return 0.2126f * r + 0.7142f * g + 0.0722f * b;
        }

        default:
            SK_ABORT("Bad dst channel name for pixel data generation: %c", name);
    }
}

// Src and Dst must be (uint32_t, PixelData) or (PixelData, uint32_t), and `dst` should be
// zero-initialized before calling. Returns the bitOffset for the next channel.
template <typename Src, typename Dst>
int copy_unaligned_bits(int numBits, int bitOffset, const Src& src, Dst& dst) {
    static_assert(std::is_same_v<Src, uint32_t> || std::is_same_v<Src, PixelData>);
    static_assert(std::is_same_v<Dst, uint32_t> || std::is_same_v<Dst, PixelData>);
    static_assert(!std::is_same_v<Src, Dst>);
    static constexpr bool kBytesToChannel = std::is_same_v<Src, PixelData>;

    int srcBitsLeft = numBits;
    while (srcBitsLeft > 0) {
        int arrayIndex = bitOffset / 8;
        int arrayBitsLeft = (arrayIndex + 1) * 8 - bitOffset;
        int copyBits = std::min(arrayBitsLeft, srcBitsLeft);

        int channelBitShift = numBits - srcBitsLeft;
        int arrayBitShift = 8 - arrayBitsLeft;

        if constexpr (kBytesToChannel) {
            dst |= ((src[arrayIndex] >> arrayBitShift) & ((1<<copyBits) - 1)) << channelBitShift;
        } else {
            dst[arrayIndex] |= ((src >> channelBitShift) & ((1<<copyBits) - 1)) << arrayBitShift;
        }
        srcBitsLeft -= copyBits;
        bitOffset += copyBits;
    }
    return bitOffset;
}

bool needs_premul(SkAlphaType srcAlphaType, SkAlphaType dstAlphaType) {
    return dstAlphaType == kPremul_SkAlphaType && (srcAlphaType == kUnpremul_SkAlphaType ||
                                                   srcAlphaType == kUnknown_SkAlphaType);
}
bool needs_unpremul(SkAlphaType srcAlphaType, SkAlphaType dstAlphaType) {
    return srcAlphaType == kPremul_SkAlphaType && (dstAlphaType == kUnpremul_SkAlphaType ||
                                                   dstAlphaType == kUnknown_SkAlphaType);
}

// Returns the number of set *bits* within PixelData.
std::pair<PixelData, size_t> gen_pixel_data(SkSpan<const Channel> dstChannels,
                                            Swizzle storeDstSwizzle,
                                            SkAlphaType dstAlphaType,
                                            SkSpan<const Channel> srcChannels,
                                            Swizzle loadSrcSwizzle,
                                            SkAlphaType srcAlphaType,
                                            bool forInput=false) {
    PixelData pixel{}; // zero-initialize all bytes
    int bitOffset = 0;
    for (size_t c = 0; c < dstChannels.size(); ++c) {
        Channel channel = dstChannels[c];
        channel.fName = apply_swizzle_to_name(dstChannels[c].fName, storeDstSwizzle);
        float srcValue = gen_channel_value(channel.fName, loadSrcSwizzle, srcChannels);

        // Handle alpha type conversion
        if (forInput && ((channel.fName == 'a' && srcAlphaType == kUnknown_SkAlphaType) ||
                         (channel.fName == '1' && dstChannels[c].fName == 'a'))) {
            // Fill junk alpha that is masked by a later read swizzle as if it were padding
            channel.fType = Pad;
            channel.fName = 'x';
        } else if (channel.fName == 'a' && srcAlphaType == kOpaque_SkAlphaType) {
            srcValue = 1.f;
            // NOTE: We don't force alpha = 1 when dstAlphaType = opaque, since that is interpreted
            // as a trust-the-user scenario and we assume input values are already opaque and don't
            // modify the alpha.
        } else if (channel.fName == 'r' || channel.fName == 'g' || channel.fName == 'b' ||
                   channel.fName == 'G') {
            if (needs_premul(srcAlphaType, dstAlphaType)) {
                // Must multiply other channels by the alpha value
                const float srcAlpha = gen_channel_value('a', loadSrcSwizzle, srcChannels);
                srcValue *= srcAlpha;
            } else if (needs_unpremul(srcAlphaType, dstAlphaType)) {
                // Must divide the other channels by the alpha value
                const float srcAlpha = gen_channel_value('a', loadSrcSwizzle, srcChannels);
                srcValue *= 1.f / srcAlpha;
            }
            // else we're the same alpha type on both sides, or a mix of opaque and unknown, in
            // which case premul vs. unpremul is a no-op.
        }

        uint32_t channelValue = channel_to_bits(channel, srcValue);
        bitOffset = copy_unaligned_bits(channel.fBits, bitOffset, channelValue, pixel);
    }

    return {pixel, bitOffset};
}

// No swizzling or data conversion variant for input data generation
std::pair<PixelData, size_t> gen_pixel_data(SkSpan<const Channel> channels,
                                            Swizzle readSwizzle,
                                            SkAlphaType alphaType) {
    return gen_pixel_data(channels, readSwizzle.invert(), alphaType,
                          channels, readSwizzle, alphaType, /*forInput=*/true);
}

const char* channel_type_name(ChannelDataType type) {
    switch (type) {
        case UNorm:  return "u";
        case Signed: return "s";
        case Float:  return "f";
        case FNorm:  return "fn";
        case sRGB:   return "srgb";
        case XR:     return "xr";
        case Pad:    return "_";
    }
    SkUNREACHABLE;
}

skia_private::TArray<SkString> print_channel_names(SkSpan<const Channel> channels) {
    skia_private::TArray<SkString> names;
    names.push_back(SkString()); // empty to align with channel values row label
    names.push_back(SkString("raw"));
    for (const Channel& c : channels) {
        const char* typeName = channel_type_name(c.fType);
        names.push_back(SkStringPrintf("%c(%s%d)", c.fName, typeName, c.fBits));
    }
    return names;
}

skia_private::TArray<SkString> print_channel_values(
        const char* prefix, SkSpan<const Channel> channels, const PixelData& pixel) {
    skia_private::TArray<SkString> values;

    values.push_back(SkString(prefix));

    values.push_back(SkString()); // Raw hex value
    for (int i = 0; i < 16; ++i) {
        values[1].appendf(" %0.2x", pixel[i]);
    }

    int bitOffset = 0;
    for (const Channel& c : channels) {
        uint32_t channelValue = 0;
        bitOffset = copy_unaligned_bits(c.fBits, bitOffset, pixel, channelValue);

        SkString binary;
        for (int i = 0; i < c.fBits; ++i) {
            binary.prependUnichar((channelValue >> i) & 1 ? '1' : '0');
        }
        float vf = channel_to_float(c, channelValue);

        SkString numeric;
        switch (c.fType) {
            case Pad:    numeric = "-"; break;
            case Signed: numeric = SkStringPrintf("%u", channelValue); break;

            case sRGB:   [[fallthrough]];
            case XR:
            case UNorm:  numeric = SkStringPrintf("0x%x / %.2f", channelValue, vf); break;

            case FNorm:  [[fallthrough]];
            case Float:  numeric = SkStringPrintf("%0.4f", vf); break;
        }
        values.push_back(SkStringPrintf("%s (%s)", binary.c_str(), numeric.c_str()));
    }

    return values;
}

void dump_string(const SkString& str, int length) {
    int strLen = SkTo<int>(str.size());
    SkASSERT(strLen <= length);
    SkDebugf("%*s", std::min(length, strLen), str.data());
    length -= strLen;
    while(length > 0) {
        SkDebugf(" ");
        length--;
    }
}

void dump_pixel_comparison(const SkString& inputName,
                           SkSpan<const Channel> inputChannels,
                           const PixelData& inputPixel,
                           const SkString& outputName,
                           SkSpan<const Channel> outputChannels,
                           const PixelData& expectedOutputPixel,
                           const PixelData& actualOutputPixel) {
    SkDebugf("Transfer from %s to %s:\n", inputName.c_str(), outputName.c_str());

    auto inputChannelNames = print_channel_names(inputChannels);
    auto inputChannelValues = print_channel_values("Input", inputChannels, inputPixel);

    auto outputChannelNames = print_channel_names(outputChannels);
    auto expectedChannelValues =
            print_channel_values("Expected", outputChannels, expectedOutputPixel);
    auto actualChannelValues =
            print_channel_values("Actual", outputChannels, actualOutputPixel);

    const int colCount = std::max(inputChannelNames.size(), outputChannelNames.size());
    auto rows = {inputChannelNames,
                 inputChannelValues,
                 outputChannelNames,
                 expectedChannelValues,
                 actualChannelValues};
    for (auto&& row : rows) {
        for (int c = 0; c < std::min(colCount, row.size()); ++c) {
            if (c == 0) {
                SkDebugf(" ");
            } else {
                SkDebugf(" | ");
            }
            int colWidth = 0;
            for (auto&& otherRow : rows) {
                if (c < otherRow.size()) {
                    colWidth = std::max(colWidth, SkTo<int>(otherRow[c].size()));
                }
            }
            dump_string(row[c], colWidth);
        }
        SkDebugf("\n");
    }
}

int channel_tolerance(SkSpan<const Channel> srcChannels, SkAlphaType srcAT,
                      SkSpan<const Channel> dstChannels, SkAlphaType dstAT) {
    bool srcHasSRGBOrGray = false;
    for (const Channel c : srcChannels) {
        srcHasSRGBOrGray |= c.fType == sRGB || c.fName == 'G';
    }
    bool dstHasSRGBOrGray = false;
    for (const Channel c : dstChannels) {
         dstHasSRGBOrGray |= c.fType == sRGB || c.fName == 'G';
    }
    // If the input or output data involves sRGB encoding/decoding or conversion to gray, or are
    // doing premul/unpremul math, we allow 1 bit of difference because of mismatches between how
    // SkRasterPipeline calculates channel values vs. the value generation in these tests.
    return srcHasSRGBOrGray ||
           dstHasSRGBOrGray ||
           needs_premul(srcAT, dstAT) ||
           needs_unpremul(srcAT, dstAT) ? 1 : 0;
}

bool compare_pixels(SkSpan<const Channel> channels,
                    const PixelData& expected,
                    const PixelData& actual,
                    int channelTolerance,
                    std::optional<char> ignoreChannel=std::nullopt) {
    int bitOffset = 0;
    for (const Channel& c : channels) {
        uint32_t actualChannelBits = 0;
        uint32_t expectedChannelBits = 0;
        copy_unaligned_bits(c.fBits, bitOffset, expected, expectedChannelBits);
        copy_unaligned_bits(c.fBits, bitOffset, actual, actualChannelBits);
        bitOffset += c.fBits;

        int64_t channelDiff = static_cast<int64_t>(actualChannelBits) -
                              static_cast<int64_t>(expectedChannelBits);
        if (c.fType != Pad && // ignore padding channels
            !(ignoreChannel.has_value() && c.fName == *ignoreChannel) && // ignore alpha channels
            std::abs(channelDiff) > channelTolerance) {
            return false;
        }
    }
    return true;
}

PixelData transfer_data(const TextureFormatXferFn& xferFn,
                        const PixelData& inputData,
                        size_t srcPixelBits,
                        size_t dstPixelBits) {
    // First do a conversion on a 1x1 image, which will represent the expected output when
    // testing various width/height/rowbyte combinations for a solid input.
    PixelData outputData{}; // zero-initialize for comparison stability on unwritten values.
    xferFn.run(1, 1, &inputData, sizeof(PixelData), &outputData, sizeof(PixelData));

    SkASSERT(srcPixelBits % sizeof(std::uint8_t) == 0);
    SkASSERT(dstPixelBits % sizeof(std::uint8_t) == 0);
    const size_t srcPixelBytes = srcPixelBits / 8;
    const size_t dstPixelBytes = dstPixelBits / 8;

    static constexpr int kMaxDim = 32; // > 128-bit SIMD processing for 8-bit formats
    using ImageBytes = std::array<uint8_t, kMaxDim*kMaxDim*sizeof(PixelData)>;
    std::unique_ptr<ImageBytes> src = std::make_unique<ImageBytes>();
    std::unique_ptr<ImageBytes> dst = std::make_unique<ImageBytes>();

    auto fill_image = [&](int w, int h, size_t rowBytes) {
        uint8_t* dataStart = src->data();
        for (int x = 0; x < w; ++x) {
            memcpy(src->data() + x*srcPixelBytes, &inputData, srcPixelBytes);
        }
        for (int y = 1; y < h; ++y) {
            memcpy(dataStart + rowBytes, dataStart, rowBytes);
            dataStart += rowBytes;
        }
    };
    auto check_image = [&](int w, int h, size_t rowBytes) {
        const uint8_t* dataStart = dst->data();
        PixelData pxData{}; // zero-initialize all bytes
        for (int y = 0; y < h; ++y) {
            for (int x = 0; x < w; ++x) {
                memcpy(&pxData, dataStart + x*dstPixelBytes, dstPixelBytes);
                if (pxData != outputData) {
                    SkDebugf("Pixel mismatch at (%d, %d) in bulk transfer.\n", x, y);
                    outputData = pxData; // propagate this error out for pixel dumping
                    return false;
                }
            }
            dataStart += rowBytes;
        }
        return true;
    };

    // RasterPipeline isn't the fastest in debug builds and transfer_data is called ~70k times
    // in this unit test, so only test a specific width and height.
    static constexpr int kWidth = 17; // > 16 to test padding logic for 128-bit SIMD processing
    static constexpr int kHeight = 7; // > 1 for multirow testing, but low to help performance

    for (bool inputDense : {true, false}) {
        size_t srcRowBytes = (inputDense ? kWidth : kMaxDim) * srcPixelBytes;
        fill_image(kWidth, kHeight, srcRowBytes);
        for (bool outputDense : {true, false}) {
            size_t dstRowBytes = (outputDense ? kWidth : kMaxDim) * dstPixelBytes;
            xferFn.run(kWidth, kHeight, src->data(), srcRowBytes, dst->data(), dstRowBytes);
            if (!check_image(kWidth, kHeight, dstRowBytes)) {
                return outputData;
            }
        }
    }
    return outputData;
}

// Define the channel layout for every SkColorType for use in generating and validating the
// result of transferring data to or from a texture format.
[[maybe_unused]] static const struct ColorTypeChannels {
    SkColorType fColorType;
    Swizzle fEffectiveSwizzle; // Derivable from channel mask
    skia_private::TArray<Channel> fChannels;
} kColorTypeChannels[] {
    {kAlpha_8_SkColorType,            Swizzle("000a"), {{'a', 8, UNorm}}},
    // NOTE: 565 and 4444 are misnamed and are BGR and ABGR respectively.
    {kRGB_565_SkColorType,            Swizzle("rgb1"), {{'b', 5, UNorm},
                                                        {'g', 6, UNorm},
                                                        {'r', 5, UNorm}}},
    {kARGB_4444_SkColorType,          Swizzle("rgba"), {{'a', 4, UNorm},
                                                        {'b', 4, UNorm},
                                                        {'g', 4, UNorm},
                                                        {'r', 4, UNorm}}},
    {kRGBA_8888_SkColorType,          Swizzle("rgba"), {{'r', 8, UNorm},
                                                        {'g', 8, UNorm},
                                                        {'b', 8, UNorm},
                                                        {'a', 8, UNorm}}},
    {kRGB_888x_SkColorType,           Swizzle("rgb1"), {{'r', 8, UNorm},
                                                        {'g', 8, UNorm},
                                                        {'b', 8, UNorm},
                                                        {'x', 8, Pad}}},
    {kBGRA_8888_SkColorType,          Swizzle("rgba"), {{'b', 8, UNorm},
                                                        {'g', 8, UNorm},
                                                        {'r', 8, UNorm},
                                                        {'a', 8, UNorm}}},
    {kRGBA_1010102_SkColorType,       Swizzle("rgba"), {{'r', 10, UNorm},
                                                        {'g', 10, UNorm},
                                                        {'b', 10, UNorm},
                                                        {'a', 2, UNorm}}},
    {kBGRA_1010102_SkColorType,       Swizzle("rgba"), {{'b', 10, UNorm},
                                                        {'g', 10, UNorm},
                                                        {'r', 10, UNorm},
                                                        {'a', 2, UNorm}}},
    {kRGB_101010x_SkColorType,        Swizzle("rgb1"), {{'r', 10, UNorm},
                                                        {'g', 10, UNorm},
                                                        {'b', 10, UNorm},
                                                        {'x', 2, Pad}}},
    {kBGR_101010x_SkColorType,        Swizzle("rgb1"), {{'b', 10, UNorm},
                                                        {'g', 10, UNorm},
                                                        {'r', 10, UNorm},
                                                        {'x', 2, Pad}}},
    {kBGR_101010x_XR_SkColorType,     Swizzle("rgb1"), {{'b', 10, XR},
                                                        {'g', 10, XR},
                                                        {'r', 10, XR},
                                                        {'x', 2, Pad}}},
    {kBGRA_10101010_XR_SkColorType,   Swizzle("rgba"), {{'x', 6, Pad}, {'b', 10, XR},
                                                        {'x', 6, Pad}, {'g', 10, XR},
                                                        {'x', 6, Pad}, {'r', 10, XR},
                                                        {'x', 6, Pad}, {'a', 10, XR}}},
    {kRGBA_10x6_SkColorType,          Swizzle("rgba"), {{'x', 6, Pad}, {'r', 10, UNorm},
                                                        {'x', 6, Pad}, {'g', 10, UNorm},
                                                        {'x', 6, Pad}, {'b', 10, UNorm},
                                                        {'x', 6, Pad}, {'a', 10, UNorm}}},
    // NOTE: The swizzle is rrr1 since we store gray in the red channel of the texture, but we use
    // 'G' as the channel to force generating gray/luminance values in the tests instead of just 'r'
    {kGray_8_SkColorType,             Swizzle("rrr1"), {{'G', 8, UNorm}}},
    {kRGBA_F16Norm_SkColorType,       Swizzle("rgba"), {{'r', 16, FNorm},
                                                        {'g', 16, FNorm},
                                                        {'b', 16, FNorm},
                                                        {'a', 16, FNorm}}},
    {kRGBA_F16_SkColorType,           Swizzle("rgba"), {{'r', 16, Float},
                                                        {'g', 16, Float},
                                                        {'b', 16, Float},
                                                        {'a', 16, Float}}},
    {kRGB_F16F16F16x_SkColorType,     Swizzle("rgb1"), {{'r', 16, Float},
                                                        {'g', 16, Float},
                                                        {'b', 16, Float},
                                                        {'x', 16, Pad}}},
    {kRGBA_F32_SkColorType,           Swizzle("rgba"), {{'r', 32, Float},
                                                        {'g', 32, Float},
                                                        {'b', 32, Float},
                                                        {'a', 32, Float}}},
    {kR8G8_unorm_SkColorType,         Swizzle("rg01"), {{'r', 8, UNorm}, {'g', 8, UNorm}}},
    {kA16_float_SkColorType,          Swizzle("000a"), {{'a', 16, Float}}},
    {kR16_float_SkColorType,          Swizzle("r001"), {{'r', 16, Float}}},
    {kR16G16_float_SkColorType,       Swizzle("rg01"), {{'r', 16, Float}, {'g', 16, Float}}},
    {kA16_unorm_SkColorType,          Swizzle("000a"), {{'a', 16, UNorm}}},
    {kR16_unorm_SkColorType,          Swizzle("r001"), {{'r', 16, UNorm}}},
    {kR16G16_unorm_SkColorType,       Swizzle("rg01"), {{'r', 16, UNorm}, {'g', 16, UNorm}}},
    {kR16G16B16A16_unorm_SkColorType, Swizzle("rgba"), {{'r', 16, UNorm},
                                                        {'g', 16, UNorm},
                                                        {'b', 16, UNorm},
                                                        {'a', 16, UNorm}}},
    {kSRGBA_8888_SkColorType,         Swizzle("rgba"), {{'r', 8, sRGB},
                                                        {'g', 8, sRGB},
                                                        {'b', 8, sRGB},
                                                        {'a', 8, UNorm}}},
    {kR8_unorm_SkColorType,           Swizzle("r001"), {{'r', 8, UNorm}}},
};
// Must include one per SkColorType except for kUnknown
static_assert(std::size(kColorTypeChannels) == kSkColorTypeCnt - 1,
              "Missing channel definition for SkColorType");

// Full definition of compatibility and behavior between SkColorType and TextureFormat:
static const FormatExpectation kExpectations[] {
    {.fFormat=TextureFormat::kUnsupported,
     .fChannels={},
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={}},

    {.fFormat=TextureFormat::kR8,
     .fChannels={{'r', 8, UNorm}},
     .fXferSwizzle=Swizzle("r001"),
     .fCompatibleColorTypes={{kR8_unorm_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()},
                             {kAlpha_8_SkColorType,  Swizzle("000r"), Swizzle("a000")},
                             {kGray_8_SkColorType,   Swizzle("rrra"), std::nullopt}}},

    {.fFormat=TextureFormat::kR16,
     .fChannels={{'r', 16, UNorm}},
     .fXferSwizzle=Swizzle("r001"),
     .fCompatibleColorTypes={{kR16_unorm_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()},
                             {kA16_unorm_SkColorType, Swizzle("000r"), Swizzle("a000")}}},

    {.fFormat=TextureFormat::kR16F,
     .fChannels={{'r', 16, Float}},
     .fXferSwizzle=Swizzle("r001"),
     .fCompatibleColorTypes={{kR16_float_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()},
                             {kA16_float_SkColorType, Swizzle("000r"), Swizzle("a000")}}},

    {.fFormat=TextureFormat::kR32F,
     .fChannels={{'r', 32, Float}},
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={{kR16_float_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kA8,
     .fChannels={{'a', 8, UNorm}},
     .fXferSwizzle=Swizzle("000a"),
     .fCompatibleColorTypes={{kAlpha_8_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kRG8,
     .fChannels={{'r', 8, UNorm}, {'g', 8, UNorm}},
     .fXferSwizzle=Swizzle("rg01"),
     .fCompatibleColorTypes={{kR8G8_unorm_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kRG16,
     .fChannels={{'r', 16, UNorm}, {'g', 16, UNorm}},
     .fXferSwizzle=Swizzle("rg01"),
     .fCompatibleColorTypes={{kR16G16_unorm_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kRG16F,
     .fChannels={{'r', 16, Float}, {'g', 16, Float}},
     .fXferSwizzle=Swizzle("rg01"),
     .fCompatibleColorTypes={{kR16G16_float_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kRG32F,
     .fChannels={{'r', 32, Float}, {'g', 32, Float}},
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={{kR16G16_float_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kRGB8,
     .fChannels={{'r', 8, UNorm}, {'g', 8, UNorm}, {'b', 8, UNorm}},
     .fXferSwizzle=Swizzle("rgb1"),
     .fCompatibleColorTypes={{kRGB_888x_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kBGR8,
     .fChannels={{'b', 8, UNorm}, {'g', 8, UNorm}, {'r', 8, UNorm}},
     .fXferSwizzle=Swizzle("rgb1"),
     .fCompatibleColorTypes={{kRGB_888x_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kB5_G6_R5,
     .fChannels={{'b', 5, UNorm}, {'g', 6, UNorm}, {'r', 5, UNorm}},
     .fXferSwizzle=Swizzle("rgb1"),
     .fCompatibleColorTypes={{kRGB_565_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kR5_G6_B5,
     .fChannels={{'r', 5, UNorm}, {'g', 6, UNorm}, {'b', 5, UNorm}},
     .fXferSwizzle=Swizzle("rgb1"),
     .fCompatibleColorTypes={{kRGB_565_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kRGB16,
     .fChannels={{'r', 16, UNorm}, {'g', 16, UNorm}, {'b', 16, UNorm}},
     .fXferSwizzle=Swizzle("rgb1"),
     .fCompatibleColorTypes={{kR16G16B16A16_unorm_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kRGB16F,
     .fChannels={{'r', 16, Float}, {'g', 16, Float}, {'b', 16, Float}},
     .fXferSwizzle=Swizzle("rgb1"),
     .fCompatibleColorTypes={{kRGB_F16F16F16x_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kRGB32F,
     .fChannels={{'r', 32, Float}, {'g', 32, Float}, {'b', 32, Float}},
     .fXferSwizzle=Swizzle("rgb1"),
     .fCompatibleColorTypes={{kRGBA_F32_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kRGB8_sRGB,
     .fChannels={{'r', 8, sRGB}, {'g', 8, sRGB}, {'b', 8, sRGB}},
     .fXferSwizzle=Swizzle("rgb1"),
     .fCompatibleColorTypes={{kSRGBA_8888_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kBGR10_XR,
     .fChannels={{'b', 10, XR}, {'g', 10, XR}, {'r', 10, XR}, {'x', 2, Pad}},
     .fXferSwizzle=Swizzle("rgb1"),
     .fCompatibleColorTypes={{kBGR_101010x_XR_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kRGBA8,
     .fChannels={{'r', 8, UNorm}, {'g', 8, UNorm}, {'b', 8, UNorm}, {'a', 8, UNorm}},
     .fXferSwizzle=Swizzle("rgba"),
     .fCompatibleColorTypes={{kRGBA_8888_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()},
                             {kBGRA_8888_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()},
                             {kRGB_888x_SkColorType,  Swizzle::RGB1(), std::nullopt}}},

    {.fFormat=TextureFormat::kRGBA16,
     .fChannels={{'r', 16, UNorm}, {'g', 16, UNorm}, {'b', 16, UNorm}, {'a', 16, UNorm}},
     .fXferSwizzle=Swizzle("rgba"),
     .fCompatibleColorTypes={{kR16G16B16A16_unorm_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kRGBA16F,
     .fChannels={{'r', 16, Float}, {'g', 16, Float}, {'b', 16, Float}, {'a', 16, Float}},
     .fXferSwizzle=Swizzle("rgba"),
     .fCompatibleColorTypes={{kRGBA_F16_SkColorType,       Swizzle::RGBA(), Swizzle::RGBA()},
                             {kRGBA_F16Norm_SkColorType,   Swizzle::RGBA(), Swizzle::RGBA()},
                             {kRGB_F16F16F16x_SkColorType, Swizzle::RGB1(), std::nullopt}}},

    {.fFormat=TextureFormat::kRGBA32F,
     .fChannels={{'r', 32, Float}, {'g', 32, Float}, {'b', 32, Float}, {'a', 32, Float}},
     .fXferSwizzle=Swizzle("rgba"),
     .fCompatibleColorTypes={{kRGBA_F32_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kRGB10_A2,
     .fChannels={{'r', 10, UNorm}, {'g', 10, UNorm}, {'b', 10, UNorm}, {'a', 2, UNorm}},
     .fXferSwizzle=Swizzle("rgba"),
     .fCompatibleColorTypes={{kRGBA_1010102_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()},
                             {kRGB_101010x_SkColorType,  Swizzle::RGB1(), std::nullopt},
                             {kBGRA_1010102_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()},
                             {kBGR_101010x_SkColorType,  Swizzle::RGB1(), std::nullopt}}},

    {.fFormat=TextureFormat::kRGBA10x6,
     .fChannels={{'x', 6, Pad}, {'r', 10, UNorm}, {'x', 6, Pad}, {'g', 10, UNorm},
                 {'x', 6, Pad}, {'b', 10, UNorm}, {'x', 6, Pad}, {'a', 10, UNorm}},
     .fXferSwizzle=Swizzle("rgba"),
     .fCompatibleColorTypes={{kRGBA_10x6_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kRGBA8_sRGB,
     .fChannels={{'r', 8, sRGB}, {'g', 8, sRGB}, {'b', 8, sRGB}, {'a', 8, UNorm}},
     .fXferSwizzle=Swizzle("rgba"),
     .fCompatibleColorTypes={{kSRGBA_8888_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kBGRA8,
     .fChannels={{'b', 8, UNorm}, {'g', 8, UNorm}, {'r', 8, UNorm}, {'a', 8, UNorm}},
     .fXferSwizzle=Swizzle("rgba"),
     .fCompatibleColorTypes={{kBGRA_8888_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()},
                             {kRGBA_8888_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()},
                             {kRGB_888x_SkColorType,  Swizzle::RGB1(), std::nullopt}}},

    {.fFormat=TextureFormat::kBGR10_A2,
     .fChannels={{'b', 10, UNorm}, {'g', 10, UNorm}, {'r', 10, UNorm}, {'a', 2, UNorm}},
     .fXferSwizzle=Swizzle("rgba"),
     .fCompatibleColorTypes={{kBGRA_1010102_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()},
                             {kBGR_101010x_SkColorType,  Swizzle::RGB1(), std::nullopt},
                             {kRGBA_1010102_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()},
                             {kRGB_101010x_SkColorType,  Swizzle::RGB1(), std::nullopt}}},

    {.fFormat=TextureFormat::kBGRA8_sRGB,
     .fChannels={{'b', 8, sRGB}, {'g', 8, sRGB}, {'r', 8, sRGB}, {'a', 8, UNorm}},
     .fXferSwizzle=Swizzle("rgba"),
     .fCompatibleColorTypes={{kSRGBA_8888_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kABGR4,
     .fChannels={{'a', 4, UNorm}, {'b', 4, UNorm}, {'g', 4, UNorm}, {'r', 4, UNorm}},
     .fXferSwizzle=Swizzle("rgba"),
     .fCompatibleColorTypes={{kARGB_4444_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kARGB4,
     .fChannels={{'a', 4, UNorm}, {'r', 4, UNorm}, {'g', 4, UNorm}, {'b', 4, UNorm}},
     .fXferSwizzle=Swizzle("rgba"),
     .fCompatibleColorTypes={{kARGB_4444_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    {.fFormat=TextureFormat::kBGRA10x6_XR,
     .fChannels={{'x', 6, Pad}, {'b', 10, XR}, {'x', 6, Pad}, {'g', 10, XR},
                 {'x', 6, Pad}, {'r', 10, XR}, {'x', 6, Pad}, {'a', 10, XR}},
     .fXferSwizzle=Swizzle("rgba"),
     .fCompatibleColorTypes={{kBGRA_10101010_XR_SkColorType, Swizzle::RGBA(), Swizzle::RGBA()}}},

    // For compressed formats, the bytes per block represents actual compressed block size, not
    // just the size of a pixel.
    {.fFormat=TextureFormat::kRGB8_ETC2,
     .fChannels={{'r', 10, UNorm}, {'g', 8, UNorm}, {'b', 8, UNorm}},
     .fCompressionType=SkTextureCompressionType::kETC2_RGB8_UNORM,
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={{kRGB_888x_SkColorType, Swizzle::RGBA(), std::nullopt}}},

    {.fFormat=TextureFormat::kRGB8_ETC2_sRGB,
     .fChannels={{'r', 10, sRGB}, {'g', 8, sRGB}, {'b', 8, sRGB}},
     .fCompressionType=SkTextureCompressionType::kETC2_RGB8_UNORM,
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={{kSRGBA_8888_SkColorType, Swizzle::RGBA(), std::nullopt}}},

    {.fFormat=TextureFormat::kRGB8_BC1,
     .fChannels={{'r', 10, UNorm}, {'g', 8, UNorm}, {'b', 8, UNorm}},
     .fCompressionType=SkTextureCompressionType::kBC1_RGB8_UNORM,
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={{kRGB_888x_SkColorType, Swizzle::RGBA(), std::nullopt}}},

    {.fFormat=TextureFormat::kRGBA8_BC1,
     .fChannels={{'r', 10, UNorm}, {'g', 8, UNorm}, {'b', 8, UNorm}, {'a', 8, UNorm}},
     .fCompressionType=SkTextureCompressionType::kBC1_RGBA8_UNORM,
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={{kRGBA_8888_SkColorType, Swizzle::RGBA(), std::nullopt},
                             {kRGB_888x_SkColorType,  Swizzle::RGB1(), std::nullopt}}},

    {.fFormat=TextureFormat::kRGBA8_BC1_sRGB,
     .fChannels={{'r', 10, sRGB}, {'g', 8, sRGB}, {'b', 8, sRGB}, {'a', 8, UNorm}},
     .fCompressionType=SkTextureCompressionType::kBC1_RGBA8_UNORM,
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={{kSRGBA_8888_SkColorType, Swizzle::RGBA(), std::nullopt}}},

    // For these multiplanar formats, we set the bytes per block assuming the UV planes are the
    // same size as the Y plane, which is an overestimate of the total texture memory.
    {.fFormat=TextureFormat::kYUV8_P2_420,
     .fChannels={{'y', 8, UNorm}, {'u', 8, UNorm}, {'v', 8, UNorm}},
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={{kRGB_888x_SkColorType, Swizzle::RGBA(), std::nullopt}}},

    {.fFormat=TextureFormat::kYUV8_P3_420,
     .fChannels={{'y', 8, UNorm}, {'u', 8, UNorm}, {'v', 8, UNorm}},
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={{kRGB_888x_SkColorType, Swizzle::RGBA(), std::nullopt}}},

    {.fFormat=TextureFormat::kYUV10x6_P2_420,
     .fChannels={{'y', 10, UNorm}, {'x', 6, Pad}, {'u', 10, UNorm}, {'x', 6, Pad},
                 {'v', 10, UNorm}, {'x', 6, Pad}},
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={{kRGBA_10x6_SkColorType, Swizzle::RGBA(), std::nullopt}}},

    {.fFormat=TextureFormat::kYUV8_P2_422,
     .fChannels={{'y', 8, UNorm}, {'u', 8, UNorm}, {'v', 8, UNorm}},
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={{kRGB_888x_SkColorType, Swizzle::RGBA(), std::nullopt}}},

    {.fFormat=TextureFormat::kYUV8_P3_422,
     .fChannels={{'y', 8, UNorm}, {'u', 8, UNorm}, {'v', 8, UNorm}},
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={{kRGB_888x_SkColorType, Swizzle::RGBA(), std::nullopt}}},

    {.fFormat=TextureFormat::kYUV10x6_P2_422,
     .fChannels={{'y', 10, UNorm}, {'x', 6, Pad}, {'u', 10, UNorm}, {'x', 6, Pad},
                 {'v', 10, UNorm}, {'x', 6, Pad}},
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={{kRGBA_10x6_SkColorType, Swizzle::RGBA(), std::nullopt}}},

    {.fFormat=TextureFormat::kYUV8_P2_444,
     .fChannels={{'y', 8, UNorm}, {'u', 8, UNorm}, {'v', 8, UNorm}},
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={{kRGB_888x_SkColorType, Swizzle::RGBA(), std::nullopt}}},

    {.fFormat=TextureFormat::kYUV8_P3_444,
     .fChannels={{'y', 8, UNorm}, {'u', 8, UNorm}, {'v', 8, UNorm}},
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={{kRGB_888x_SkColorType, Swizzle::RGBA(), std::nullopt}}},

    {.fFormat=TextureFormat::kYUV10x6_P2_444,
     .fChannels={{'y', 10, UNorm}, {'x', 6, Pad}, {'u', 10, UNorm}, {'x', 6, Pad},
                 {'v', 10, UNorm}, {'x', 6, Pad}},
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={{kRGBA_10x6_SkColorType, Swizzle::RGBA(), std::nullopt}}},

    {.fFormat=TextureFormat::kExternal,
     // We don't really know this, but most Skia behavior defaults to assuming 8-bit color
     .fChannels={{'r', 8, UNorm}, {'g', 8, UNorm}, {'b', 8, UNorm}, {'a', 8, UNorm}},
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={{kRGBA_8888_SkColorType, Swizzle::RGBA(), std::nullopt},
                             {kRGB_888x_SkColorType,  Swizzle::RGB1(), std::nullopt}}},

    {.fFormat=TextureFormat::kS8,
     .fChannels={{'s', 8, Signed}},
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={}},

    {.fFormat=TextureFormat::kD16,
     .fChannels={{'d', 16, UNorm}},
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={}},

    {.fFormat=TextureFormat::kD32F,
     .fChannels={{'d', 32, Float}},
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={}},

    {.fFormat=TextureFormat::kD24_S8,
     .fChannels={{'d', 24, UNorm}, {'s', 8, Signed}},
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={}},

    {.fFormat=TextureFormat::kD32F_S8,
     .fChannels={{'d', 32, Float}, {'s', 8, Signed}},
     .fXferSwizzle=std::nullopt,
     .fCompatibleColorTypes={}},
};

// Match convention used with WrapTexture, where unknown alpha is forced to opaque via swizzle
Swizzle adjust_swizzle_for_alphatype(Swizzle readSwizzle, SkAlphaType at) {
    if (at == kUnknown_SkAlphaType) {
        return Swizzle::Concat(readSwizzle, Swizzle::RGB1());
    } else {
        return readSwizzle;
    }
}

bool raster_pipeline_allowed_in_transfer(SkSpan<const Channel> src,
                                         SkSpan<const Channel> dst,
                                         const SkColorSpaceXformSteps& cs) {
    // Colorspace conversions have to happen in raster pipeline
    if (SkToBool(cs)) {
        return true;
    }

    if (src.size() != dst.size()) {
        // Converting between RGB and RGBA shouldn't require raster pipeline,
        // but larger channel swizzlings such as RGBA to A do.
        if ((src.size() != 3 && src.size() != 4) ||
            (dst.size() != 3 && dst.size() != 4)) {
            return true;
        }
    }

    auto summarize = [](SkSpan<const Channel> channels) {
        int maxChannelBitDepth = 0;
        ChannelDataType primaryType = UNorm;
        bool holdsLuminance = false;
        for (const Channel& c : channels) {
            holdsLuminance = c.fName == 'G';
            if (c.fType != Pad) {
                maxChannelBitDepth = std::max(maxChannelBitDepth, c.fBits);
                primaryType = std::max(primaryType, c.fType);
            }
        }
        return std::make_tuple(maxChannelBitDepth, primaryType, holdsLuminance);
    };

    auto [srcBits, srcType, srcLum] = summarize(src);
    auto [dstBits, dstType, dstLum] = summarize(dst);

    // Data bit representation has to go through raster pipeline
    if (srcBits != dstBits || srcType != dstType) {
        return true;
    }

    // Computing a luminance value has to go through raster pipeline
    if (dstLum && !srcLum && (src.size() != 1 || src[0].fName != 'a')) {
        return true;
    }
    return false;
}

void validate_optimal_xfer_fn(skiatest::Reporter* r,
                              const TextureFormatXferFn& xferFn,
                              const SkColorSpaceXformSteps& cs,
                              std::optional<char> ignoreChannel,
                              const SkString& srcName,
                              SkSpan<const Channel> srcChannels,
                              const PixelData& srcData,
                              const SkString& dstName,
                              SkSpan<const Channel> dstChannels,
                              const PixelData& dstData) {
    // If the transferred data remains unmodified, confirm that the transfer function detected that
    // it could have been an identity transfer. We skip that due to red herrings when there's a
    // colorspace (which would force raster pipeline always, but because of our RGB->BGR synthetic
    // space it can sometimes leave computed values unmodified). We skip when there's a channel
    // change (which can sometimes appear as an identity if certain channels remain 0). We skip the
    // case when it's an ignore-src + force-opaque, because TextureFormatXferfn will choose that
    // for alpha-only color types with unknown alpha but when the source data is alpha-only + opaque
    // it looks equivalent.
    const bool identityRedHerring = SkToBool(cs) ||
                                    srcChannels.size() != dstChannels.size() ||
                                    xferFn.isIgnoreSrcForceOpaque();
    if (!identityRedHerring &&  memcmp(&srcData, &dstData, sizeof(PixelData)) == 0) {
        REPORTER_ASSERT(r, xferFn.isIdentity(), "Expected identity xfer fn between %s -> %s",
                        srcName.c_str(), dstName.c_str());
    }

    // The flip-side, if `xferFn` claims its the identity, then the data should match as well.
    if (xferFn.isIdentity()) {
        if (!compare_pixels(dstChannels, srcData, dstData, /*channelTolerance=*/0, ignoreChannel)) {
            dump_pixel_comparison(srcName, srcChannels, srcData,
                                  dstName, dstChannels, srcData, dstData);
            REPORTER_ASSERT(r, false, "Xfer fn between %s -> %s claimed identity but was not",
                            srcName.c_str(), dstName.c_str());
            STOP_ON_TRANSFER_FAILURE
        }
    }

    // Otherwise, check that the transfer function is only relying on the raster pipeline when
    // necessary. And if it is using raster pipeline, then it's not mixing the SIMD xfer ops.
    if (xferFn.usesRasterPipeline()) {
        REPORTER_ASSERT(r, raster_pipeline_allowed_in_transfer(srcChannels, dstChannels, cs),
                        "Transfer between %s -> %s unexpected uses raster pipeline",
                        srcName.c_str(), dstName.c_str());
        if (xferFn.usesXferOps()) {
            // The only time it's okay to mix xfer ops and RP is for handling kDrop/kPadAlpha since
            // the format is not representable with raster pipeline.
            REPORTER_ASSERT(r, xferFn.isDropOrPadAlpha(),
                            "Transfer between %s -> %s mixes transfer methods",
                            srcName.c_str(), dstName.c_str());
        }
    }
}

void test_format_transfers(skiatest::Reporter* r,
                           const FormatExpectation& textureFormat,
                           const ColorTypeExpectation& textureCT,
                           SkAlphaType srcAT,
                           SkAlphaType dstAT,
                           bool applyCS) {
    // When transferring to CPU->GPU, we want to apply the textureCT's write swizzle, but if that
    // is undefined because rendering is disabled, just use RGBA.
    Swizzle writeSwizzle = textureCT.fWriteSwizzle.value_or(Swizzle::RGBA());

    // Adjust the R8 channel to be 'G' for gray-storing textures so that gen_pixel_data includes
    // any conversion to or from luminance.
    const bool isRedOnly = textureFormat.fChannels.size() == 1 &&
                           textureFormat.fChannels[0].fName == 'r';
    skia_private::TArray<Channel> expectedTextureChannels = textureFormat.fChannels;
    if (textureCT.fColorType == kGray_8_SkColorType) {
        SkASSERT(isRedOnly);
        expectedTextureChannels[0].fName = 'G';
    }

    // This colorspace is constructed to have a linear gamma curve and an identity gamut transform
    // so that any operations that it applies are just multiplies by 0 or 1. Anything else adds
    // minor bit variations to processed data, making checking expectations harder.
    sk_sp<SkColorSpace> srcCS = SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear,
                                                      SkNamedGamut::kXYZ);
    sk_sp<SkColorSpace> dstCS = applyCS ? srcCS->makeColorSpin() : srcCS;
    SkColorSpaceXformSteps csSteps{srcCS.get(), srcAT, dstCS.get(), dstAT};

    SkString gpuLabel = SkStringPrintf("GPU format %s as %s",
            TextureFormatName(textureFormat.fFormat),
            ToolUtils::colortype_name(textureCT.fColorType));
    // Transfering from srcCT into a GPU textureFormat interpreted as textureCT
    for (const ColorTypeChannels& src : kColorTypeChannels) {
        // Adjust srcAT as if they had created a valid SkBitmap, which may mean skipping. Since we
        // test every srcAT possibility, if the srcAT changes, we skip to avoid running extra work.
        SkAlphaType validSrcAT;
        if (!SkColorTypeValidateAlphaType(src.fColorType, srcAT, &validSrcAT) ||
            validSrcAT != srcAT) {
            continue;
        }
        // Adjust the read swizzle to account for unknown alpha type semantics
        Swizzle readSwizzle = adjust_swizzle_for_alphatype(textureCT.fReadSwizzle, dstAT);
        std::optional<TextureFormatXferFn> xferFn =
                TextureFormatXferFn::MakeCpuToGpu(src.fColorType,
                                                  csSteps,
                                                  textureFormat.fFormat,
                                                  readSwizzle);
        REPORTER_ASSERT(r, textureFormat.fXferSwizzle.has_value() == xferFn.has_value());

        if (textureFormat.fXferSwizzle.has_value() && xferFn.has_value()) {
            SkString ctLabel =
                    SkStringPrintf("CPU colortype %s", ToolUtils::colortype_name(src.fColorType));
            auto [cpuPixel, cpuPixelBits] = gen_pixel_data(src.fChannels, Swizzle::RGBA(), srcAT);

            // The expected GPU value is formed by applying the source colortype's effective
            // swizzle (i.e. fill in missing channels), and the format's compatible colortype's
            // write swizzle to the channel definition of format.
            Swizzle loadSrc = src.fEffectiveSwizzle;
            if (applyCS) {
                // The colorspace conversion is constructed to be a spin via gamut transform matrix,
                // so the end effect should match a rotation swizzle on R,G,B (ignoring alpha).
                loadSrc = Swizzle::Concat(loadSrc, Swizzle("gbra"));
            }

            auto [expectedGpuPixel, gpuPixelBits] = gen_pixel_data(expectedTextureChannels,
                                                                   writeSwizzle,
                                                                   dstAT,
                                                                   src.fChannels,
                                                                   loadSrc,
                                                                   validSrcAT);
            PixelData actualGpuPixel = transfer_data(*xferFn, cpuPixel, cpuPixelBits, gpuPixelBits);

            // The data transfer can skip alpha handling if we know that all samples/reads are going
            // to override it with 1.0 anyways. Testing the final readSwizzle includes both color
            // type semantics that induce the swizzle and requesting unknown alpha type.
            std::optional<char> ignoreChannel;
            if (readSwizzle[3] == '1') {
                // If the format stores alpha in r, we need to ignore the r value.
                ignoreChannel = isRedOnly ? 'r' : 'a';
            }

            // Confirm the transfer is as optimized as possible
            validate_optimal_xfer_fn(r, *xferFn, csSteps, ignoreChannel,
                                     ctLabel, src.fChannels, cpuPixel,
                                     gpuLabel, expectedTextureChannels, expectedGpuPixel);

            const int tol = channel_tolerance(src.fChannels, validSrcAT,
                                              expectedTextureChannels, dstAT);
            if (!compare_pixels(expectedTextureChannels, expectedGpuPixel, actualGpuPixel, tol,
                                ignoreChannel)) {
                dump_pixel_comparison(ctLabel,
                                      src.fChannels,
                                      cpuPixel,
                                      gpuLabel,
                                      textureFormat.fChannels,
                                      expectedGpuPixel,
                                      actualGpuPixel);
                REPORTER_ASSERT(r, false,  "Pixel mismatch uploading from %s, alpha %s -> %s%s",
                                ctLabel.c_str(),
                                ToolUtils::alphatype_name(validSrcAT),
                                ToolUtils::alphatype_name(dstAT),
                                applyCS ? " with colorspace conversion" : "");
                STOP_ON_TRANSFER_FAILURE
            }
        }
    }

    // Transfering from a GPU textureFormat interpreted as textureCT into dstCT
    for (const ColorTypeChannels& dst : kColorTypeChannels) {
        // Adjust dstAT as if they had created a valid SkBitmap, which may mean skipping. Since we
        // test every dstAT possibility, if the dstAT changes, we skip to avoid running extra work.
        SkAlphaType validDstAT;
        if (!SkColorTypeValidateAlphaType(dst.fColorType, dstAT, &validDstAT) ||
            validDstAT != dstAT) {
            continue;
        }
        // Adjust the read swizzle to account for unknown alpha type semantics
        Swizzle readSwizzle = adjust_swizzle_for_alphatype(textureCT.fReadSwizzle, srcAT);
        std::optional<TextureFormatXferFn> xferFn =
                TextureFormatXferFn::MakeGpuToCpu(textureFormat.fFormat,
                                                  readSwizzle,
                                                  csSteps,
                                                  dst.fColorType);
        REPORTER_ASSERT(r, textureFormat.fXferSwizzle.has_value() == xferFn.has_value());

        if (textureFormat.fXferSwizzle.has_value() && xferFn.has_value()) {
            SkString ctLabel =
                    SkStringPrintf("CPU colortype %s", ToolUtils::colortype_name(dst.fColorType));
            auto [gpuPixel, gpuPixelBits] = gen_pixel_data(expectedTextureChannels,
                                                           textureCT.fReadSwizzle,
                                                           srcAT);

            // The expected CPU value is formed by applying the TextureFormat's implicit transfer
            // swizzle (i.e. fill in missing channels), its compatible colortype's read swizzle
            // to the channel definition of the dst color type.
            Swizzle loadSrc = Swizzle::Concat(*textureFormat.fXferSwizzle, readSwizzle);
            if (applyCS) {
                loadSrc = Swizzle::Concat(loadSrc, Swizzle("gbra")); // See above
            }
            auto [expectedCpuPixel, cpuPixelBits] = gen_pixel_data(dst.fChannels,
                                                                   Swizzle::RGBA(),
                                                                   dstAT,
                                                                   expectedTextureChannels,
                                                                   loadSrc,
                                                                   srcAT);
            // Confirm the transfer is as optimized as possible
            validate_optimal_xfer_fn(r, *xferFn, csSteps, /*ignoreChannel=*/std::nullopt,
                                     gpuLabel, expectedTextureChannels, gpuPixel,
                                     ctLabel, dst.fChannels, expectedCpuPixel);

            PixelData actualCpuPixel = transfer_data(*xferFn, gpuPixel, gpuPixelBits, cpuPixelBits);

            const int tol = channel_tolerance(expectedTextureChannels, srcAT,
                                              dst.fChannels, dstAT);
            if (!compare_pixels(dst.fChannels, expectedCpuPixel, actualCpuPixel, tol)) {
                dump_pixel_comparison(gpuLabel,
                                      textureFormat.fChannels,
                                      gpuPixel,
                                      ctLabel,
                                      dst.fChannels,
                                      expectedCpuPixel,
                                      actualCpuPixel);
                REPORTER_ASSERT(r, false,  "Pixel mismatch reading back to %s, alpha %s -> %s%s",
                                ctLabel.c_str(),
                                ToolUtils::alphatype_name(srcAT),
                                ToolUtils::alphatype_name(dstAT),
                                applyCS ? " with colorspace conversion" : "");
                STOP_ON_TRANSFER_FAILURE
            }
        }
    }
}

void run_texture_format_test(skiatest::Reporter* r, const Caps* caps, TextureFormat format) {
    bool foundExpectation = false;
    for (auto&& e : kExpectations) {
        if (e.fFormat != format) {
            continue;
        }

        // Should only find it once
        REPORTER_ASSERT(r, !foundExpectation, "Format expectation listed multiple times");
        foundExpectation = true;

        skiatest::ReporterContext scope(r, SkStringPrintf("Format %s", TextureFormatName(format)));

        // Found the expectation for the requested format. Check fixed properties first.
        REPORTER_ASSERT(r, e.fCompressionType == TextureFormatCompressionType(format));
        REPORTER_ASSERT(r, e.bytesPerBlock() == TextureFormatBytesPerBlock(format));
        REPORTER_ASSERT(r, e.channelMask() == TextureFormatChannelMask(format));
        REPORTER_ASSERT(r, e.hasDepthOrStencil() == TextureFormatIsDepthOrStencil(format));
        REPORTER_ASSERT(r, e.hasDepth() == TextureFormatHasDepth(format));
        REPORTER_ASSERT(r, e.hasStencil() == TextureFormatHasStencil(format));
        REPORTER_ASSERT(r, e.isMultiplanar() == TextureFormatIsMultiplanar(format));
        REPORTER_ASSERT(r, e.autoClamps() == TextureFormatAutoClamps(format));
        REPORTER_ASSERT(r, e.isFloatingPoint() == TextureFormatIsFloatingPoint(format));

        // Verify compatible color types
        auto [baseColorType, _] = TextureFormatColorTypeInfo(format);
        if (baseColorType == kUnknown_SkColorType) {
            REPORTER_ASSERT(r, e.fCompatibleColorTypes.empty());
        } else {
            // Should be the first listed compatible color type
            REPORTER_ASSERT(r, !e.fCompatibleColorTypes.empty());
            REPORTER_ASSERT(r, e.fCompatibleColorTypes[0].fColorType == baseColorType);
        }

        for (int c = 0; c <= kLastEnum_SkColorType; ++c) {
            SkColorType ct = static_cast<SkColorType>(c);

            skiatest::ReporterContext ctScope{
                    r, SkStringPrintf("color type %s\n", ToolUtils::colortype_name(ct))};

            bool foundColorExpectation = false;
            for (auto&& ec : e.fCompatibleColorTypes) {
                if (ec.fColorType == ct) {
                    // Expected to be compatible (and should only find it once)
                    REPORTER_ASSERT(r, !foundColorExpectation,
                                    "Color type listed multiple times: %s",
                                    ToolUtils::colortype_name(ec.fColorType));
                    foundColorExpectation = true;

                    // Check swizzles and transfers here, the rest of the color type checks happen
                    // outside the loop based on `foundColorExpectation`.
                    Swizzle actualReadSwizzle = ReadSwizzleForColorType(ct, format);
                    REPORTER_ASSERT(r, ec.fReadSwizzle == actualReadSwizzle,
                                    "actual %s vs. expected %s",
                                    actualReadSwizzle.asString().c_str(),
                                    ec.fReadSwizzle.asString().c_str());

                    auto actualWriteSwizzle = WriteSwizzleForColorType(ct, format);
                    if (ec.fWriteSwizzle.has_value()) {
                        REPORTER_ASSERT(r, actualWriteSwizzle.has_value());
                        REPORTER_ASSERT(r, ec.fWriteSwizzle == actualWriteSwizzle,
                                        "actual %s vs. expected %s",
                                        actualWriteSwizzle ? actualWriteSwizzle->asString().c_str()
                                                           : "null",
                                        ec.fWriteSwizzle->asString().c_str());
                    } else {
                        REPORTER_ASSERT(r, !actualWriteSwizzle.has_value());
                        // This is a proxy for "the format can represent CT, and there are some
                        // formats that can render CT, but this format does not render w/ CT".
                        TextureInfo renderableInfo = caps->getDefaultSampledTextureInfo(
                                ct, Mipmapped::kNo, Protected::kNo, Renderable::kYes);
                        REPORTER_ASSERT(r, format != TextureInfoPriv::ViewFormat(renderableInfo));
                    }

                    // Test sampled and readable copy info
                    TextureInfo sampledInfo = caps->getDefaultSampledTextureInfo(
                            ct, Mipmapped::kNo, Protected::kNo, Renderable::kNo);
                    if (sampledInfo.isValid() &&
                        TextureInfoPriv::ViewFormat(sampledInfo) == format) {
                        REPORTER_ASSERT(r, caps->isTexturable(sampledInfo));
                        REPORTER_ASSERT(r, caps->isReadable(sampledInfo));
                        TextureInfo copyInfo = caps->getTextureInfoForSampledCopy(
                                sampledInfo, Mipmapped::kNo);
                        REPORTER_ASSERT(r, copyInfo.isValid());
                    }

                    TextureInfo readableInfo = caps->getDefaultReadableTextureInfo(
                            format, Protected::kNo);
                    if (readableInfo.isValid() &&
                        TextureInfoPriv::ViewFormat(readableInfo) == format) {
                        REPORTER_ASSERT(r, caps->isReadable(readableInfo));
                        TextureInfo copyInfo = caps->getTextureInfoForReadableCopy(readableInfo);
                        REPORTER_ASSERT(r, copyInfo.isValid());
                    }

                    TextureInfo storageInfo = caps->getDefaultReadableStorageTextureInfo(
                            format, Protected::kNo);
                    if (storageInfo.isValid() &&
                        TextureInfoPriv::ViewFormat(storageInfo) == format) {
                        REPORTER_ASSERT(r, caps->isStorage(storageInfo));
                        REPORTER_ASSERT(r, caps->isReadable(storageInfo));
                    }

                    // Test all combinations of alpha type x 2 (texture vs cpu) and whether or not
                    // colorspace conversions are handled in the transfer.
                    static constexpr int kAlphaTypeCount = (int) kLastEnum_SkAlphaType + 1;
                    for (bool applyCS : {false, true}) {
                        for (int srcAT = 0; srcAT < kAlphaTypeCount; ++srcAT) {
                            for (int dstAT = 0; dstAT < kAlphaTypeCount; ++dstAT) {
                                test_format_transfers(r, e, ec,
                                                      static_cast<SkAlphaType>(srcAT),
                                                      static_cast<SkAlphaType>(dstAT),
                                                      applyCS);
                            }
                        }
                    }
                }
            }

            // If we found an expectation, it should be detected as compatible (and false otherwise)
            const bool actualCompatible = AreColorTypeAndFormatCompatible(ct, format);
            REPORTER_ASSERT(r, foundColorExpectation == actualCompatible,
                            "actual (%d) vs expected (%d)",
                            actualCompatible, foundColorExpectation);
        }
    }

    // All formats should have expectations
    REPORTER_ASSERT(r, foundExpectation, "Missing expectation for %s", TextureFormatName(format));
}

DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(TextureFormatTest, r, ctx, CtsEnforcement::kApiLevel_202604) {
    for (int i = 0; i < kTextureFormatCount; ++i) {
        run_texture_format_test(r, ctx->priv().caps(), static_cast<TextureFormat>(i));
    }
}

} // namespace skgpu::graphite
