// XGL tests
//
// Copyright (C) 2014 LunarG, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// Blit (copy, clear, and resolve) tests

#include "test_common.h"
#include "xgltestbinding.h"

#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))

namespace xgl_testing {

size_t get_format_size(XGL_FORMAT format);

class Environment : public ::testing::Environment {
public:
    Environment();

    bool parse_args(int argc, char **argv);

    virtual void SetUp();
    virtual void TearDown();

    const std::vector<Device *> &devices() { return devs_; }
    Device &default_device() { return *(devs_[default_dev_]); }

private:
    XGL_APPLICATION_INFO app_;
    int default_dev_;

    std::vector<Device *> devs_;
};

class ImageChecker {
public:
    explicit ImageChecker(const XGL_IMAGE_CREATE_INFO &info, const std::vector<XGL_BUFFER_IMAGE_COPY> &regions)
        : info_(info), regions_(regions), pattern_(HASH) {}
    explicit ImageChecker(const XGL_IMAGE_CREATE_INFO &info, const std::vector<XGL_IMAGE_SUBRESOURCE_RANGE> &ranges);
    explicit ImageChecker(const XGL_IMAGE_CREATE_INFO &info);

    void set_solid_pattern(const std::vector<uint8_t> &solid);

    XGL_GPU_SIZE buffer_size() const;
    bool fill(Buffer &buf) const { return walk(FILL, buf); }
    bool fill(Image &img) const { return walk(FILL, img); }
    bool check(Buffer &buf) const { return walk(CHECK, buf); }
    bool check(Image &img) const { return walk(CHECK, img); }

    const std::vector<XGL_BUFFER_IMAGE_COPY> &regions() const { return regions_; }

    static void hash_salt_generate() { hash_salt_++; }

private:
    enum Action {
        FILL,
        CHECK,
    };

    enum Pattern {
        HASH,
        SOLID,
    };

    size_t buffer_cpp() const;
    XGL_SUBRESOURCE_LAYOUT buffer_layout(const XGL_BUFFER_IMAGE_COPY &region) const;

    bool walk(Action action, Buffer &buf) const;
    bool walk(Action action, Image &img) const;
    bool walk_region(Action action, const XGL_BUFFER_IMAGE_COPY &region, const XGL_SUBRESOURCE_LAYOUT &layout, void *data) const;

    std::vector<uint8_t> pattern_hash(const XGL_IMAGE_SUBRESOURCE &subres, const XGL_OFFSET3D &offset) const;

    static uint32_t hash_salt_;

    XGL_IMAGE_CREATE_INFO info_;
    std::vector<XGL_BUFFER_IMAGE_COPY> regions_;

    Pattern pattern_;
    std::vector<uint8_t> pattern_solid_;
};

Environment::Environment() :
    default_dev_(0)
{
    app_.sType = XGL_STRUCTURE_TYPE_APPLICATION_INFO;
    app_.pAppName = "xgl_testing";
    app_.appVersion = 1;
    app_.pEngineName = "xgl_testing";
    app_.engineVersion = 1;
    app_.apiVersion = XGL_MAKE_VERSION(0, 22, 0);
}

bool Environment::parse_args(int argc, char **argv)
{
    int i;

    for (i = 1; i < argc; i++) {
#define ARG(name) (strcmp(argv[i], name) == 0)
#define ARG_P(name) (i < argc - 1 && ARG(name))
        if (ARG_P("--gpu")) {
            default_dev_ = atoi(argv[++i]);
        } else {
            break;
        }
#undef ARG
#undef ARG_P
    }

    if (i < argc) {
        std::cout <<
            "invalid argument: " << argv[i] << "\n\n" <<
            "Usage: " << argv[0] << " <options>\n\n" <<
            "Options:\n"
            "  --gpu <n>  Use GPU<n> as the default GPU\n";

        return false;
    }

    return true;
}

void Environment::SetUp()
{
    XGL_PHYSICAL_GPU gpus[XGL_MAX_PHYSICAL_GPUS];
    uint32_t count;
    XGL_RESULT err;

    err = xglInitAndEnumerateGpus(&app_, NULL, ARRAY_SIZE(gpus), &count, gpus);
    ASSERT_EQ(XGL_SUCCESS, err);
    ASSERT_GT(count, default_dev_);

    devs_.reserve(count);
    for (uint32_t i = 0; i < count; i++) {
        devs_.push_back(new Device(gpus[i]));
        if (i == default_dev_) {
            devs_[i]->init();
            ASSERT_NE(true, devs_[i]->graphics_queues().empty());
        }
    }
}

void Environment::TearDown()
{
    // destroy devices first
    for (std::vector<Device *>::iterator it = devs_.begin(); it != devs_.end(); it++)
        delete *it;
    devs_.clear();

    uint32_t dummy_count;
    xglInitAndEnumerateGpus(&app_, NULL, 0, &dummy_count, NULL);
}

uint32_t ImageChecker::hash_salt_;

ImageChecker::ImageChecker(const XGL_IMAGE_CREATE_INFO &info)
    : info_(info), regions_(), pattern_(HASH)
{
    // create a region for every mip level in array slice 0
    XGL_GPU_SIZE offset = 0;
    for (uint32_t lv = 0; lv < info_.mipLevels; lv++) {
        XGL_BUFFER_IMAGE_COPY region = {};

        region.bufferOffset = offset;
        region.imageSubresource.mipLevel = lv;
        region.imageSubresource.arraySlice = 0;
        region.imageExtent = Image::extent(info_.extent, lv);

        if (info_.usage & XGL_IMAGE_USAGE_DEPTH_STENCIL_BIT) {
            if (info_.format != XGL_FMT_S8_UINT) {
                region.imageSubresource.aspect = XGL_IMAGE_ASPECT_DEPTH;
                regions_.push_back(region);
            }

            if (info_.format == XGL_FMT_D16_UNORM_S8_UINT ||
                info_.format == XGL_FMT_D32_SFLOAT_S8_UINT ||
                info_.format == XGL_FMT_S8_UINT) {
                region.imageSubresource.aspect = XGL_IMAGE_ASPECT_STENCIL;
                regions_.push_back(region);
            }
        } else {
            region.imageSubresource.aspect = XGL_IMAGE_ASPECT_COLOR;
            regions_.push_back(region);
        }

        offset += buffer_layout(region).size;
    }

    // arraySize should be limited in our tests.  If this proves to be an
    // issue, we can store only the regions for array slice 0 and be smart.
    if (info_.arraySize > 1) {
        const XGL_GPU_SIZE slice_pitch = offset;
        const uint32_t slice_region_count = regions_.size();

        regions_.reserve(slice_region_count * info_.arraySize);

        for (uint32_t slice = 1; slice < info_.arraySize; slice++) {
            for (uint32_t i = 0; i < slice_region_count; i++) {
                XGL_BUFFER_IMAGE_COPY region = regions_[i];

                region.bufferOffset += slice_pitch * slice;
                region.imageSubresource.arraySlice = slice;
                regions_.push_back(region);
            }
        }
    }
}

ImageChecker::ImageChecker(const XGL_IMAGE_CREATE_INFO &info, const std::vector<XGL_IMAGE_SUBRESOURCE_RANGE> &ranges)
    : info_(info), regions_(), pattern_(HASH)
{
    XGL_GPU_SIZE offset = 0;
    for (std::vector<XGL_IMAGE_SUBRESOURCE_RANGE>::const_iterator it = ranges.begin();
         it != ranges.end(); it++) {
        for (uint32_t lv = 0; lv < it->mipLevels; lv++) {
            for (uint32_t slice = 0; slice < it->arraySize; slice++) {
                XGL_BUFFER_IMAGE_COPY region = {};
                region.bufferOffset = offset;
                region.imageSubresource = Image::subresource(*it, lv, slice);
                region.imageExtent = Image::extent(info_.extent, lv);

                regions_.push_back(region);

                offset += buffer_layout(region).size;
            }
        }
    }
}

void ImageChecker::set_solid_pattern(const std::vector<uint8_t> &solid)
{
    pattern_ = SOLID;
    pattern_solid_.clear();
    pattern_solid_.reserve(buffer_cpp());
    for (int i = 0; i < buffer_cpp(); i++)
        pattern_solid_.push_back(solid[i % solid.size()]);
}

size_t ImageChecker::buffer_cpp() const
{
    return get_format_size(info_.format);
}

XGL_SUBRESOURCE_LAYOUT ImageChecker::buffer_layout(const XGL_BUFFER_IMAGE_COPY &region) const
{
    XGL_SUBRESOURCE_LAYOUT layout = {};
    layout.offset = region.bufferOffset;
    layout.rowPitch = buffer_cpp() * region.imageExtent.width;
    layout.depthPitch = layout.rowPitch * region.imageExtent.height;
    layout.size = layout.depthPitch * region.imageExtent.depth;

    return layout;
}

XGL_GPU_SIZE ImageChecker::buffer_size() const
{
    XGL_GPU_SIZE size = 0;

    for (std::vector<XGL_BUFFER_IMAGE_COPY>::const_iterator it = regions_.begin();
         it != regions_.end(); it++) {
        const XGL_SUBRESOURCE_LAYOUT layout = buffer_layout(*it);
        if (size < layout.offset + layout.size)
            size = layout.offset + layout.size;
    }

    return size;
}

bool ImageChecker::walk_region(Action action, const XGL_BUFFER_IMAGE_COPY &region,
                               const XGL_SUBRESOURCE_LAYOUT &layout, void *data) const
{
    for (int32_t z = 0; z < region.imageExtent.depth; z++) {
        for (int32_t y = 0; y < region.imageExtent.height; y++) {
            for (int32_t x = 0; x < region.imageExtent.width; x++) {
                uint8_t *dst = static_cast<uint8_t *>(data);
                dst += layout.offset + layout.depthPitch * z +
                    layout.rowPitch * y + buffer_cpp() * x;

                XGL_OFFSET3D offset = region.imageOffset;
                offset.x += x;
                offset.y += y;
                offset.z += z;

                const std::vector<uint8_t> &val = (pattern_ == HASH) ?
                    pattern_hash(region.imageSubresource, offset) :
                    pattern_solid_;
                assert(val.size() == buffer_cpp());

                if (action == FILL) {
                    memcpy(dst, &val[0], val.size());
                } else {
                    for (int i = 0; i < val.size(); i++) {
                        EXPECT_EQ(val[i], dst[i]) <<
                            "Offset is: (" << x << ", " << y << ", " << z << ")";
                        if (val[i] != dst[i])
                            return false;
                    }
                }
            }
        }
    }

    return true;
}

bool ImageChecker::walk(Action action, Buffer &buf) const
{
    void *data = buf.map();
    if (!data)
        return false;

    std::vector<XGL_BUFFER_IMAGE_COPY>::const_iterator it;
    for (it = regions_.begin(); it != regions_.end(); it++) {
        if (!walk_region(action, *it, buffer_layout(*it), data))
            break;
    }

    buf.unmap();

    return (it == regions_.end());
}

bool ImageChecker::walk(Action action, Image &img) const
{
    void *data = img.map();
    if (!data)
        return false;

    std::vector<XGL_BUFFER_IMAGE_COPY>::const_iterator it;
    for (it = regions_.begin(); it != regions_.end(); it++) {
        if (!walk_region(action, *it, img.subresource_layout(it->imageSubresource), data))
            break;
    }

    img.unmap();

    return (it == regions_.end());
}

std::vector<uint8_t> ImageChecker::pattern_hash(const XGL_IMAGE_SUBRESOURCE &subres, const XGL_OFFSET3D &offset) const
{
#define HASH_BYTE(val, b) static_cast<uint8_t>((static_cast<uint32_t>(val) >> (b * 8)) & 0xff)
#define HASH_BYTES(val) HASH_BYTE(val, 0), HASH_BYTE(val, 1), HASH_BYTE(val, 2), HASH_BYTE(val, 3)
    const unsigned char input[] = {
        HASH_BYTES(hash_salt_),
        HASH_BYTES(subres.mipLevel),
        HASH_BYTES(subres.arraySlice),
        HASH_BYTES(offset.x),
        HASH_BYTES(offset.y),
        HASH_BYTES(offset.z),
    };
    unsigned long hash = 5381;

    for (int32_t i = 0; i < ARRAY_SIZE(input); i++)
        hash = ((hash << 5) + hash) + input[i];

    const uint8_t output[4] = { HASH_BYTES(hash) };
#undef HASH_BYTES
#undef HASH_BYTE

    std::vector<uint8_t> val;
    val.reserve(buffer_cpp());
    for (int i = 0; i < buffer_cpp(); i++)
        val.push_back(output[i % 4]);

    return val;
}

size_t get_format_size(XGL_FORMAT format)
{
    static const struct format_info {
        size_t size;
        uint32_t channel_count;
    } format_table[XGL_NUM_FMT] = {
        [XGL_FMT_UNDEFINED]            = { 0,  0 },
        [XGL_FMT_R4G4_UNORM]           = { 1,  2 },
        [XGL_FMT_R4G4_USCALED]         = { 1,  2 },
        [XGL_FMT_R4G4B4A4_UNORM]       = { 2,  4 },
        [XGL_FMT_R4G4B4A4_USCALED]     = { 2,  4 },
        [XGL_FMT_R5G6B5_UNORM]         = { 2,  3 },
        [XGL_FMT_R5G6B5_USCALED]       = { 2,  3 },
        [XGL_FMT_R5G5B5A1_UNORM]       = { 2,  4 },
        [XGL_FMT_R5G5B5A1_USCALED]     = { 2,  4 },
        [XGL_FMT_R8_UNORM]             = { 1,  1 },
        [XGL_FMT_R8_SNORM]             = { 1,  1 },
        [XGL_FMT_R8_USCALED]           = { 1,  1 },
        [XGL_FMT_R8_SSCALED]           = { 1,  1 },
        [XGL_FMT_R8_UINT]              = { 1,  1 },
        [XGL_FMT_R8_SINT]              = { 1,  1 },
        [XGL_FMT_R8_SRGB]              = { 1,  1 },
        [XGL_FMT_R8G8_UNORM]           = { 2,  2 },
        [XGL_FMT_R8G8_SNORM]           = { 2,  2 },
        [XGL_FMT_R8G8_USCALED]         = { 2,  2 },
        [XGL_FMT_R8G8_SSCALED]         = { 2,  2 },
        [XGL_FMT_R8G8_UINT]            = { 2,  2 },
        [XGL_FMT_R8G8_SINT]            = { 2,  2 },
        [XGL_FMT_R8G8_SRGB]            = { 2,  2 },
        [XGL_FMT_R8G8B8_UNORM]         = { 3,  3 },
        [XGL_FMT_R8G8B8_SNORM]         = { 3,  3 },
        [XGL_FMT_R8G8B8_USCALED]       = { 3,  3 },
        [XGL_FMT_R8G8B8_SSCALED]       = { 3,  3 },
        [XGL_FMT_R8G8B8_UINT]          = { 3,  3 },
        [XGL_FMT_R8G8B8_SINT]          = { 3,  3 },
        [XGL_FMT_R8G8B8_SRGB]          = { 3,  3 },
        [XGL_FMT_R8G8B8A8_UNORM]       = { 4,  4 },
        [XGL_FMT_R8G8B8A8_SNORM]       = { 4,  4 },
        [XGL_FMT_R8G8B8A8_USCALED]     = { 4,  4 },
        [XGL_FMT_R8G8B8A8_SSCALED]     = { 4,  4 },
        [XGL_FMT_R8G8B8A8_UINT]        = { 4,  4 },
        [XGL_FMT_R8G8B8A8_SINT]        = { 4,  4 },
        [XGL_FMT_R8G8B8A8_SRGB]        = { 4,  4 },
        [XGL_FMT_R10G10B10A2_UNORM]    = { 4,  4 },
        [XGL_FMT_R10G10B10A2_SNORM]    = { 4,  4 },
        [XGL_FMT_R10G10B10A2_USCALED]  = { 4,  4 },
        [XGL_FMT_R10G10B10A2_SSCALED]  = { 4,  4 },
        [XGL_FMT_R10G10B10A2_UINT]     = { 4,  4 },
        [XGL_FMT_R10G10B10A2_SINT]     = { 4,  4 },
        [XGL_FMT_R16_UNORM]            = { 2,  1 },
        [XGL_FMT_R16_SNORM]            = { 2,  1 },
        [XGL_FMT_R16_USCALED]          = { 2,  1 },
        [XGL_FMT_R16_SSCALED]          = { 2,  1 },
        [XGL_FMT_R16_UINT]             = { 2,  1 },
        [XGL_FMT_R16_SINT]             = { 2,  1 },
        [XGL_FMT_R16_SFLOAT]           = { 2,  1 },
        [XGL_FMT_R16G16_UNORM]         = { 4,  2 },
        [XGL_FMT_R16G16_SNORM]         = { 4,  2 },
        [XGL_FMT_R16G16_USCALED]       = { 4,  2 },
        [XGL_FMT_R16G16_SSCALED]       = { 4,  2 },
        [XGL_FMT_R16G16_UINT]          = { 4,  2 },
        [XGL_FMT_R16G16_SINT]          = { 4,  2 },
        [XGL_FMT_R16G16_SFLOAT]        = { 4,  2 },
        [XGL_FMT_R16G16B16_UNORM]      = { 6,  3 },
        [XGL_FMT_R16G16B16_SNORM]      = { 6,  3 },
        [XGL_FMT_R16G16B16_USCALED]    = { 6,  3 },
        [XGL_FMT_R16G16B16_SSCALED]    = { 6,  3 },
        [XGL_FMT_R16G16B16_UINT]       = { 6,  3 },
        [XGL_FMT_R16G16B16_SINT]       = { 6,  3 },
        [XGL_FMT_R16G16B16_SFLOAT]     = { 6,  3 },
        [XGL_FMT_R16G16B16A16_UNORM]   = { 8,  4 },
        [XGL_FMT_R16G16B16A16_SNORM]   = { 8,  4 },
        [XGL_FMT_R16G16B16A16_USCALED] = { 8,  4 },
        [XGL_FMT_R16G16B16A16_SSCALED] = { 8,  4 },
        [XGL_FMT_R16G16B16A16_UINT]    = { 8,  4 },
        [XGL_FMT_R16G16B16A16_SINT]    = { 8,  4 },
        [XGL_FMT_R16G16B16A16_SFLOAT]  = { 8,  4 },
        [XGL_FMT_R32_UINT]             = { 4,  1 },
        [XGL_FMT_R32_SINT]             = { 4,  1 },
        [XGL_FMT_R32_SFLOAT]           = { 4,  1 },
        [XGL_FMT_R32G32_UINT]          = { 8,  2 },
        [XGL_FMT_R32G32_SINT]          = { 8,  2 },
        [XGL_FMT_R32G32_SFLOAT]        = { 8,  2 },
        [XGL_FMT_R32G32B32_UINT]       = { 12, 3 },
        [XGL_FMT_R32G32B32_SINT]       = { 12, 3 },
        [XGL_FMT_R32G32B32_SFLOAT]     = { 12, 3 },
        [XGL_FMT_R32G32B32A32_UINT]    = { 16, 4 },
        [XGL_FMT_R32G32B32A32_SINT]    = { 16, 4 },
        [XGL_FMT_R32G32B32A32_SFLOAT]  = { 16, 4 },
        [XGL_FMT_R64_SFLOAT]           = { 8,  1 },
        [XGL_FMT_R64G64_SFLOAT]        = { 16, 2 },
        [XGL_FMT_R64G64B64_SFLOAT]     = { 24, 3 },
        [XGL_FMT_R64G64B64A64_SFLOAT]  = { 32, 4 },
        [XGL_FMT_R11G11B10_UFLOAT]     = { 4,  3 },
        [XGL_FMT_R9G9B9E5_UFLOAT]      = { 4,  3 },
        [XGL_FMT_D16_UNORM]            = { 2,  1 },
        [XGL_FMT_D24_UNORM]            = { 3,  1 },
        [XGL_FMT_D32_SFLOAT]           = { 4,  1 },
        [XGL_FMT_S8_UINT]              = { 1,  1 },
        [XGL_FMT_D16_UNORM_S8_UINT]    = { 3,  2 },
        [XGL_FMT_D24_UNORM_S8_UINT]    = { 4,  2 },
        [XGL_FMT_D32_SFLOAT_S8_UINT]   = { 4,  2 },
        [XGL_FMT_BC1_UNORM]            = { 8,  4 },
        [XGL_FMT_BC1_SRGB]             = { 8,  4 },
        [XGL_FMT_BC2_UNORM]            = { 16, 4 },
        [XGL_FMT_BC2_SRGB]             = { 16, 4 },
        [XGL_FMT_BC3_UNORM]            = { 16, 4 },
        [XGL_FMT_BC3_SRGB]             = { 16, 4 },
        [XGL_FMT_BC4_UNORM]            = { 8,  4 },
        [XGL_FMT_BC4_SNORM]            = { 8,  4 },
        [XGL_FMT_BC5_UNORM]            = { 16, 4 },
        [XGL_FMT_BC5_SNORM]            = { 16, 4 },
        [XGL_FMT_BC6H_UFLOAT]          = { 16, 4 },
        [XGL_FMT_BC6H_SFLOAT]          = { 16, 4 },
        [XGL_FMT_BC7_UNORM]            = { 16, 4 },
        [XGL_FMT_BC7_SRGB]             = { 16, 4 },
        // TODO: Initialize remaining compressed formats.
        [XGL_FMT_ETC2_R8G8B8_UNORM]    = { 0, 0 },
        [XGL_FMT_ETC2_R8G8B8A1_UNORM]  = { 0, 0 },
        [XGL_FMT_ETC2_R8G8B8A8_UNORM]  = { 0, 0 },
        [XGL_FMT_EAC_R11_UNORM]        = { 0, 0 },
        [XGL_FMT_EAC_R11_SNORM]        = { 0, 0 },
        [XGL_FMT_EAC_R11G11_UNORM]     = { 0, 0 },
        [XGL_FMT_EAC_R11G11_SNORM]     = { 0, 0 },
        [XGL_FMT_ASTC_4x4_UNORM]       = { 0, 0 },
        [XGL_FMT_ASTC_4x4_SRGB]        = { 0, 0 },
        [XGL_FMT_ASTC_4x5_UNORM]       = { 0, 0 },
        [XGL_FMT_ASTC_4x5_SRGB]        = { 0, 0 },
        [XGL_FMT_ASTC_5x5_UNORM]       = { 0, 0 },
        [XGL_FMT_ASTC_5x5_SRGB]        = { 0, 0 },
        [XGL_FMT_ASTC_6x5_UNORM]       = { 0, 0 },
        [XGL_FMT_ASTC_6x5_SRGB]        = { 0, 0 },
        [XGL_FMT_ASTC_6x6_UNORM]       = { 0, 0 },
        [XGL_FMT_ASTC_6x6_SRGB]        = { 0, 0 },
        [XGL_FMT_ASTC_8x5_UNORM]       = { 0, 0 },
        [XGL_FMT_ASTC_8x5_SRGB]        = { 0, 0 },
        [XGL_FMT_ASTC_8x6_UNORM]       = { 0, 0 },
        [XGL_FMT_ASTC_8x6_SRGB]        = { 0, 0 },
        [XGL_FMT_ASTC_8x8_UNORM]       = { 0, 0 },
        [XGL_FMT_ASTC_8x8_SRGB]        = { 0, 0 },
        [XGL_FMT_ASTC_10x5_UNORM]      = { 0, 0 },
        [XGL_FMT_ASTC_10x5_SRGB]       = { 0, 0 },
        [XGL_FMT_ASTC_10x6_UNORM]      = { 0, 0 },
        [XGL_FMT_ASTC_10x6_SRGB]       = { 0, 0 },
        [XGL_FMT_ASTC_10x8_UNORM]      = { 0, 0 },
        [XGL_FMT_ASTC_10x8_SRGB]       = { 0, 0 },
        [XGL_FMT_ASTC_10x10_UNORM]     = { 0, 0 },
        [XGL_FMT_ASTC_10x10_SRGB]      = { 0, 0 },
        [XGL_FMT_ASTC_12x10_UNORM]     = { 0, 0 },
        [XGL_FMT_ASTC_12x10_SRGB]      = { 0, 0 },
        [XGL_FMT_ASTC_12x12_UNORM]     = { 0, 0 },
        [XGL_FMT_ASTC_12x12_SRGB]      = { 0, 0 },
        [XGL_FMT_B5G6R5_UNORM]         = { 2, 3 },
        [XGL_FMT_B5G6R5_USCALED]       = { 2, 3 },
        [XGL_FMT_B8G8R8_UNORM]         = { 3, 3 },
        [XGL_FMT_B8G8R8_SNORM]         = { 3, 3 },
        [XGL_FMT_B8G8R8_USCALED]       = { 3, 3 },
        [XGL_FMT_B8G8R8_SSCALED]       = { 3, 3 },
        [XGL_FMT_B8G8R8_UINT]          = { 3, 3 },
        [XGL_FMT_B8G8R8_SINT]          = { 3, 3 },
        [XGL_FMT_B8G8R8_SRGB]          = { 3, 3 },
        [XGL_FMT_B8G8R8A8_UNORM]       = { 4, 4 },
        [XGL_FMT_B8G8R8A8_SNORM]       = { 4, 4 },
        [XGL_FMT_B8G8R8A8_USCALED]     = { 4, 4 },
        [XGL_FMT_B8G8R8A8_SSCALED]     = { 4, 4 },
        [XGL_FMT_B8G8R8A8_UINT]        = { 4, 4 },
        [XGL_FMT_B8G8R8A8_SINT]        = { 4, 4 },
        [XGL_FMT_B8G8R8A8_SRGB]        = { 4, 4 },
        [XGL_FMT_B10G10R10A2_UNORM]    = { 4, 4 },
        [XGL_FMT_B10G10R10A2_SNORM]    = { 4, 4 },
        [XGL_FMT_B10G10R10A2_USCALED]  = { 4, 4 },
        [XGL_FMT_B10G10R10A2_SSCALED]  = { 4, 4 },
        [XGL_FMT_B10G10R10A2_UINT]     = { 4, 4 },
        [XGL_FMT_B10G10R10A2_SINT]     = { 4, 4 },
    };

    return format_table[format].size;
}

XGL_EXTENT3D get_mip_level_extent(const XGL_EXTENT3D &extent, uint32_t mip_level)
{
    const XGL_EXTENT3D ext = {
        (extent.width  >> mip_level) ? extent.width  >> mip_level : 1,
        (extent.height >> mip_level) ? extent.height >> mip_level : 1,
        (extent.depth  >> mip_level) ? extent.depth  >> mip_level : 1,
    };

    return ext;
}

}; // namespace xgl_testing

namespace {

#define DO(action) ASSERT_EQ(true, action);

xgl_testing::Environment *environment;

class XglCmdBlitTest : public ::testing::Test {
protected:
    XglCmdBlitTest() :
        dev_(environment->default_device()),
        queue_(*dev_.graphics_queues()[0]),
        cmd_(dev_, xgl_testing::CmdBuffer::create_info(XGL_QUEUE_TYPE_GRAPHICS))
    {
        // make sure every test uses a different pattern
        xgl_testing::ImageChecker::hash_salt_generate();
    }

    bool submit_and_done()
    {
        queue_.submit(cmd_, mem_refs_);
        queue_.wait();
        mem_refs_.clear();
        return true;
    }

    void add_memory_ref(const xgl_testing::Object &obj, XGL_FLAGS flags)
    {
        const std::vector<XGL_GPU_MEMORY> mems = obj.memories();
        for (std::vector<XGL_GPU_MEMORY>::const_iterator it = mems.begin(); it != mems.end(); it++) {
            std::vector<XGL_MEMORY_REF>::iterator ref;
            for (ref = mem_refs_.begin(); ref != mem_refs_.end(); ref++) {
                if (ref->mem == *it)
                    break;
            }

            if (ref == mem_refs_.end()) {
                XGL_MEMORY_REF tmp = {};
                tmp.mem = *it;
                tmp.flags = flags;
                mem_refs_.push_back(tmp);
            } else {
                ref->flags &= flags;
            }
        }
    }

    xgl_testing::Device &dev_;
    xgl_testing::Queue &queue_;
    xgl_testing::CmdBuffer cmd_;

    std::vector<XGL_MEMORY_REF> mem_refs_;
};

typedef XglCmdBlitTest XglCmdFillBufferTest;

TEST_F(XglCmdFillBufferTest, Basic)
{
    xgl_testing::Buffer buf;

    buf.init(dev_, 20);
    add_memory_ref(buf, 0);

    cmd_.begin();
    xglCmdFillBuffer(cmd_.obj(), buf.obj(), 0, 4, 0x11111111);
    xglCmdFillBuffer(cmd_.obj(), buf.obj(), 4, 16, 0x22222222);
    cmd_.end();

    submit_and_done();

    const uint32_t *data = static_cast<const uint32_t *>(buf.map());
    EXPECT_EQ(0x11111111, data[0]);
    EXPECT_EQ(0x22222222, data[1]);
    EXPECT_EQ(0x22222222, data[2]);
    EXPECT_EQ(0x22222222, data[3]);
    EXPECT_EQ(0x22222222, data[4]);
    buf.unmap();
}

TEST_F(XglCmdFillBufferTest, Large)
{
    const XGL_GPU_SIZE size = 32 * 1024 * 1024;
    xgl_testing::Buffer buf;

    buf.init(dev_, size);
    add_memory_ref(buf, 0);

    cmd_.begin();
    xglCmdFillBuffer(cmd_.obj(), buf.obj(), 0, size / 2, 0x11111111);
    xglCmdFillBuffer(cmd_.obj(), buf.obj(), size / 2, size / 2, 0x22222222);
    cmd_.end();

    submit_and_done();

    const uint32_t *data = static_cast<const uint32_t *>(buf.map());
    XGL_GPU_SIZE offset;
    for (offset = 0; offset < size / 2; offset += 4)
        EXPECT_EQ(0x11111111, data[offset / 4]) << "Offset is: " << offset;
    for (; offset < size; offset += 4)
        EXPECT_EQ(0x22222222, data[offset / 4]) << "Offset is: " << offset;
    buf.unmap();
}

TEST_F(XglCmdFillBufferTest, Overlap)
{
    xgl_testing::Buffer buf;

    buf.init(dev_, 64);
    add_memory_ref(buf, 0);

    cmd_.begin();
    xglCmdFillBuffer(cmd_.obj(), buf.obj(), 0, 48, 0x11111111);
    xglCmdFillBuffer(cmd_.obj(), buf.obj(), 32, 32, 0x22222222);
    cmd_.end();

    submit_and_done();

    const uint32_t *data = static_cast<const uint32_t *>(buf.map());
    XGL_GPU_SIZE offset;
    for (offset = 0; offset < 32; offset += 4)
        EXPECT_EQ(0x11111111, data[offset / 4]) << "Offset is: " << offset;
    for (; offset < 64; offset += 4)
        EXPECT_EQ(0x22222222, data[offset / 4]) << "Offset is: " << offset;
    buf.unmap();
}

TEST_F(XglCmdFillBufferTest, MultiAlignments)
{
    xgl_testing::Buffer bufs[9];
    XGL_GPU_SIZE size = 4;

    cmd_.begin();
    for (int i = 0; i < ARRAY_SIZE(bufs); i++) {
        bufs[i].init(dev_, size);
        add_memory_ref(bufs[i], 0);
        xglCmdFillBuffer(cmd_.obj(), bufs[i].obj(), 0, size, 0x11111111);
        size <<= 1;
    }
    cmd_.end();

    submit_and_done();

    size = 4;
    for (int i = 0; i < ARRAY_SIZE(bufs); i++) {
        const uint32_t *data = static_cast<const uint32_t *>(bufs[i].map());
        XGL_GPU_SIZE offset;
        for (offset = 0; offset < size; offset += 4)
            EXPECT_EQ(0x11111111, data[offset / 4]) << "Buffser is: " << i << "\n" <<
                                                       "Offset is: " << offset;
        bufs[i].unmap();

        size <<= 1;
    }
}

typedef XglCmdBlitTest XglCmdCopyBufferTest;

TEST_F(XglCmdCopyBufferTest, Basic)
{
    xgl_testing::Buffer src, dst;

    src.init(dev_, 4);
    uint32_t *data = static_cast<uint32_t *>(src.map());
    data[0] = 0x11111111;
    src.unmap();
    add_memory_ref(src, XGL_MEMORY_REF_READ_ONLY_BIT);

    dst.init(dev_, 4);
    add_memory_ref(dst, 0);

    cmd_.begin();
    XGL_BUFFER_COPY region = {};
    region.copySize = 4;
    xglCmdCopyBuffer(cmd_.obj(), src.obj(), dst.obj(), 1, &region);
    cmd_.end();

    submit_and_done();

    data = static_cast<uint32_t *>(dst.map());
    EXPECT_EQ(0x11111111, data[0]);
    dst.unmap();
}

TEST_F(XglCmdCopyBufferTest, Large)
{
    const XGL_GPU_SIZE size = 32 * 1024 * 1024;
    xgl_testing::Buffer src, dst;

    src.init(dev_, size);
    uint32_t *data = static_cast<uint32_t *>(src.map());
    XGL_GPU_SIZE offset;
    for (offset = 0; offset < size; offset += 4)
        data[offset / 4] = offset;
    src.unmap();
    add_memory_ref(src, XGL_MEMORY_REF_READ_ONLY_BIT);

    dst.init(dev_, size);
    add_memory_ref(dst, 0);

    cmd_.begin();
    XGL_BUFFER_COPY region = {};
    region.copySize = size;
    xglCmdCopyBuffer(cmd_.obj(), src.obj(), dst.obj(), 1, &region);
    cmd_.end();

    submit_and_done();

    data = static_cast<uint32_t *>(dst.map());
    for (offset = 0; offset < size; offset += 4)
        EXPECT_EQ(offset, data[offset / 4]);
    dst.unmap();
}

TEST_F(XglCmdCopyBufferTest, MultiAlignments)
{
    const XGL_BUFFER_COPY regions[] = {
        /* well aligned */
        {  0,   0,  256 },
        {  0, 256,  128 },
        {  0, 384,   64 },
        {  0, 448,   32 },
        {  0, 480,   16 },
        {  0, 496,    8 },

        /* ill aligned */
        {  7, 510,   16 },
        { 16, 530,   13 },
        { 32, 551,   16 },
        { 45, 570,   15 },
        { 50, 590,    1 },
    };
    xgl_testing::Buffer src, dst;

    src.init(dev_, 256);
    uint8_t *data = static_cast<uint8_t *>(src.map());
    for (int i = 0; i < 256; i++)
        data[i] = i;
    src.unmap();
    add_memory_ref(src, XGL_MEMORY_REF_READ_ONLY_BIT);

    dst.init(dev_, 1024);
    add_memory_ref(dst, 0);

    cmd_.begin();
    xglCmdCopyBuffer(cmd_.obj(), src.obj(), dst.obj(), ARRAY_SIZE(regions), regions);
    cmd_.end();

    submit_and_done();

    data = static_cast<uint8_t *>(dst.map());
    for (int i = 0; i < ARRAY_SIZE(regions); i++) {
        const XGL_BUFFER_COPY &r = regions[i];

        for (int j = 0; j < r.copySize; j++) {
            EXPECT_EQ(r.srcOffset + j, data[r.destOffset + j]) <<
                "Region is: " << i << "\n" <<
                "Offset is: " << r.destOffset + j;
        }
    }
    dst.unmap();
}

TEST_F(XglCmdCopyBufferTest, RAWHazard)
{
    xgl_testing::Buffer bufs[3];
    XGL_EVENT_CREATE_INFO event_info;
    XGL_EVENT event;
    XGL_MEMORY_REQUIREMENTS mem_req;
    size_t data_size = sizeof(mem_req);
    XGL_RESULT err;

    //        typedef struct _XGL_EVENT_CREATE_INFO
    //        {
    //            XGL_STRUCTURE_TYPE                      sType;      // Must be XGL_STRUCTURE_TYPE_EVENT_CREATE_INFO
    //            const void*                             pNext;      // Pointer to next structure
    //            XGL_FLAGS                               flags;      // Reserved
    //        } XGL_EVENT_CREATE_INFO;
    memset(&event_info, 0, sizeof(event_info));
    event_info.sType = XGL_STRUCTURE_TYPE_EVENT_CREATE_INFO;

    err = xglCreateEvent(dev_.obj(), &event_info, &event);
    ASSERT_XGL_SUCCESS(err);

    err = xglGetObjectInfo(event, XGL_INFO_TYPE_MEMORY_REQUIREMENTS,
                           &data_size, &mem_req);
    ASSERT_XGL_SUCCESS(err);

    //        XGL_RESULT XGLAPI xglAllocMemory(
    //            XGL_DEVICE                                  device,
    //            const XGL_MEMORY_ALLOC_INFO*                pAllocInfo,
    //            XGL_GPU_MEMORY*                             pMem);
    XGL_MEMORY_ALLOC_INFO mem_info;
    XGL_GPU_MEMORY event_mem;

    ASSERT_NE(0, mem_req.size) << "xglGetObjectInfo (Event): Failed - expect events to require memory";

    memset(&mem_info, 0, sizeof(mem_info));
    mem_info.sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
    mem_info.allocationSize = mem_req.size;
    mem_info.memType = mem_req.memType;
    mem_info.memPriority = XGL_MEMORY_PRIORITY_NORMAL;
    mem_info.memProps = XGL_MEMORY_PROPERTY_SHAREABLE_BIT;
    err = xglAllocMemory(dev_.obj(), &mem_info, &event_mem);
    ASSERT_XGL_SUCCESS(err);

    err = xglBindObjectMemory(event, 0, event_mem, 0);
    ASSERT_XGL_SUCCESS(err);

    err = xglResetEvent(event);
    ASSERT_XGL_SUCCESS(err);

    for (int i = 0; i < ARRAY_SIZE(bufs); i++) {
        bufs[i].init(dev_, 4);
        add_memory_ref(bufs[i], 0);

        uint32_t *data = static_cast<uint32_t *>(bufs[i].map());
        data[0] = 0x22222222 * (i + 1);
        bufs[i].unmap();
    }

    cmd_.begin();

    xglCmdFillBuffer(cmd_.obj(), bufs[0].obj(), 0, 4, 0x11111111);
    // is this necessary?
    XGL_BUFFER_MEMORY_BARRIER memory_barrier = bufs[0].buffer_memory_barrier(
            XGL_MEMORY_OUTPUT_COPY_BIT, XGL_MEMORY_INPUT_COPY_BIT, 0, 4);
    XGL_BUFFER_MEMORY_BARRIER *pmemory_barrier = &memory_barrier;

    XGL_SET_EVENT set_events[] = { XGL_SET_EVENT_TRANSFER_COMPLETE };
    XGL_PIPELINE_BARRIER pipeline_barrier = {};
    pipeline_barrier.sType = XGL_STRUCTURE_TYPE_PIPELINE_BARRIER;
    pipeline_barrier.eventCount = 1;
    pipeline_barrier.pEvents = set_events;
    pipeline_barrier.waitEvent = XGL_WAIT_EVENT_TOP_OF_PIPE;
    pipeline_barrier.memBarrierCount = 1;
    pipeline_barrier.pMemBarriers = (const void **)&pmemory_barrier;
    xglCmdPipelineBarrier(cmd_.obj(), &pipeline_barrier);

    XGL_BUFFER_COPY region = {};
    region.copySize = 4;
    xglCmdCopyBuffer(cmd_.obj(), bufs[0].obj(), bufs[1].obj(), 1, &region);

    memory_barrier = bufs[1].buffer_memory_barrier(
            XGL_MEMORY_OUTPUT_COPY_BIT, XGL_MEMORY_INPUT_COPY_BIT, 0, 4);
    pmemory_barrier = &memory_barrier;
    pipeline_barrier.sType = XGL_STRUCTURE_TYPE_PIPELINE_BARRIER;
    pipeline_barrier.eventCount = 1;
    pipeline_barrier.pEvents = set_events;
    pipeline_barrier.waitEvent = XGL_WAIT_EVENT_TOP_OF_PIPE;
    pipeline_barrier.memBarrierCount = 1;
    pipeline_barrier.pMemBarriers = (const void **)&pmemory_barrier;
    xglCmdPipelineBarrier(cmd_.obj(), &pipeline_barrier);

    xglCmdCopyBuffer(cmd_.obj(), bufs[1].obj(), bufs[2].obj(), 1, &region);

    /* Use xglCmdSetEvent and xglCmdWaitEvents to test them.
     * This could be xglCmdPipelineBarrier.
     */
    xglCmdSetEvent(cmd_.obj(), event, XGL_SET_EVENT_TRANSFER_COMPLETE);

    // Additional commands could go into the buffer here before the wait.

    memory_barrier = bufs[1].buffer_memory_barrier(
            XGL_MEMORY_OUTPUT_COPY_BIT, XGL_MEMORY_INPUT_CPU_READ_BIT, 0, 4);
    pmemory_barrier = &memory_barrier;
    XGL_EVENT_WAIT_INFO wait_info = {};
    wait_info.sType = XGL_STRUCTURE_TYPE_EVENT_WAIT_INFO;
    wait_info.eventCount = 1;
    wait_info.pEvents = &event;
    wait_info.waitEvent = XGL_WAIT_EVENT_TOP_OF_PIPE;
    wait_info.memBarrierCount = 1;
    wait_info.pMemBarriers = (const void **)&pmemory_barrier;
    xglCmdWaitEvents(cmd_.obj(), &wait_info);

    cmd_.end();

    submit_and_done();

    const uint32_t *data = static_cast<const uint32_t *>(bufs[2].map());
    EXPECT_EQ(0x11111111, data[0]);
    bufs[2].unmap();

    // All done with event memory, clean up
    err = xglBindObjectMemory(event, 0, XGL_NULL_HANDLE, 0);
    ASSERT_XGL_SUCCESS(err);

    err = xglDestroyObject(event);
    ASSERT_XGL_SUCCESS(err);
}

class XglCmdBlitImageTest : public XglCmdBlitTest {
protected:
    void init_test_formats(XGL_FLAGS features)
    {
        first_linear_format_ = XGL_FMT_UNDEFINED;
        first_optimal_format_ = XGL_FMT_UNDEFINED;

        for (std::vector<xgl_testing::Device::Format>::const_iterator it = dev_.formats().begin();
             it != dev_.formats().end(); it++) {
            if (it->features & features) {
                test_formats_.push_back(*it);

                if (it->tiling == XGL_LINEAR_TILING &&
                    first_linear_format_ == XGL_FMT_UNDEFINED)
                    first_linear_format_ = it->format;
                if (it->tiling == XGL_OPTIMAL_TILING &&
                    first_optimal_format_ == XGL_FMT_UNDEFINED)
                    first_optimal_format_ = it->format;
            }
        }
    }

    void init_test_formats()
    {
        init_test_formats(static_cast<XGL_FLAGS>(-1));
    }

    void fill_src(xgl_testing::Image &img, const xgl_testing::ImageChecker &checker)
    {
        if (img.transparent()) {
            checker.fill(img);
            return;
        }

        ASSERT_EQ(true, img.copyable());

        xgl_testing::Buffer in_buf;
        in_buf.init(dev_, checker.buffer_size());
        checker.fill(in_buf);

        add_memory_ref(in_buf, XGL_MEMORY_REF_READ_ONLY_BIT);
        add_memory_ref(img, 0);

        // copy in and tile
        cmd_.begin();
        xglCmdCopyBufferToImage(cmd_.obj(), in_buf.obj(), img.obj(),
                checker.regions().size(), &checker.regions()[0]);
        cmd_.end();

        submit_and_done();
    }

    void check_dst(xgl_testing::Image &img, const xgl_testing::ImageChecker &checker)
    {
        if (img.transparent()) {
            DO(checker.check(img));
            return;
        }

        ASSERT_EQ(true, img.copyable());

        xgl_testing::Buffer out_buf;
        out_buf.init(dev_, checker.buffer_size());

        add_memory_ref(img, XGL_MEMORY_REF_READ_ONLY_BIT);
        add_memory_ref(out_buf, 0);

        // copy out and linearize
        cmd_.begin();
        xglCmdCopyImageToBuffer(cmd_.obj(), img.obj(), out_buf.obj(),
                checker.regions().size(), &checker.regions()[0]);
        cmd_.end();

        submit_and_done();

        DO(checker.check(out_buf));
    }

    std::vector<xgl_testing::Device::Format> test_formats_;
    XGL_FORMAT first_linear_format_;
    XGL_FORMAT first_optimal_format_;
};

class XglCmdCopyBufferToImageTest : public XglCmdBlitImageTest {
protected:
    virtual void SetUp()
    {
        XglCmdBlitTest::SetUp();
        init_test_formats(XGL_FORMAT_IMAGE_COPY_BIT);
        ASSERT_NE(true, test_formats_.empty());
    }

    void test_copy_memory_to_image(const XGL_IMAGE_CREATE_INFO &img_info, const xgl_testing::ImageChecker &checker)
    {
        xgl_testing::Buffer buf;
        xgl_testing::Image img;

        buf.init(dev_, checker.buffer_size());
        checker.fill(buf);
        add_memory_ref(buf, XGL_MEMORY_REF_READ_ONLY_BIT);

        img.init(dev_, img_info);
        add_memory_ref(img, 0);

        cmd_.begin();
        xglCmdCopyBufferToImage(cmd_.obj(), buf.obj(), img.obj(),
                checker.regions().size(), &checker.regions()[0]);
        cmd_.end();

        submit_and_done();

        check_dst(img, checker);
    }

    void test_copy_memory_to_image(const XGL_IMAGE_CREATE_INFO &img_info, const std::vector<XGL_BUFFER_IMAGE_COPY> &regions)
    {
        xgl_testing::ImageChecker checker(img_info, regions);
        test_copy_memory_to_image(img_info, checker);
    }

    void test_copy_memory_to_image(const XGL_IMAGE_CREATE_INFO &img_info)
    {
        xgl_testing::ImageChecker checker(img_info);
        test_copy_memory_to_image(img_info, checker);
    }
};

TEST_F(XglCmdCopyBufferToImageTest, Basic)
{
    for (std::vector<xgl_testing::Device::Format>::const_iterator it = test_formats_.begin();
         it != test_formats_.end(); it++) {

        // not sure what to do here
        if (it->format == XGL_FMT_UNDEFINED ||
            (it->format >= XGL_FMT_B8G8R8_UNORM &&
             it->format <= XGL_FMT_B8G8R8_SRGB))
            continue;

        XGL_IMAGE_CREATE_INFO img_info = xgl_testing::Image::create_info();
        img_info.imageType = XGL_IMAGE_2D;
        img_info.format = it->format;
        img_info.extent.width = 64;
        img_info.extent.height = 64;
        img_info.tiling = it->tiling;

        test_copy_memory_to_image(img_info);
    }
}

class XglCmdCopyImageToBufferTest : public XglCmdBlitImageTest {
protected:
    virtual void SetUp()
    {
        XglCmdBlitTest::SetUp();
        init_test_formats(XGL_FORMAT_IMAGE_COPY_BIT);
        ASSERT_NE(true, test_formats_.empty());
    }

    void test_copy_image_to_memory(const XGL_IMAGE_CREATE_INFO &img_info, const xgl_testing::ImageChecker &checker)
    {
        xgl_testing::Image img;
        xgl_testing::Buffer buf;

        img.init(dev_, img_info);
        fill_src(img, checker);
        add_memory_ref(img, XGL_MEMORY_REF_READ_ONLY_BIT);

        buf.init(dev_, checker.buffer_size());
        add_memory_ref(buf, 0);

        cmd_.begin();
        xglCmdCopyImageToBuffer(cmd_.obj(), img.obj(), buf.obj(),
                checker.regions().size(), &checker.regions()[0]);
        cmd_.end();

        submit_and_done();

        checker.check(buf);
    }

    void test_copy_image_to_memory(const XGL_IMAGE_CREATE_INFO &img_info, const std::vector<XGL_BUFFER_IMAGE_COPY> &regions)
    {
        xgl_testing::ImageChecker checker(img_info, regions);
        test_copy_image_to_memory(img_info, checker);
    }

    void test_copy_image_to_memory(const XGL_IMAGE_CREATE_INFO &img_info)
    {
        xgl_testing::ImageChecker checker(img_info);
        test_copy_image_to_memory(img_info, checker);
    }
};

TEST_F(XglCmdCopyImageToBufferTest, Basic)
{
    for (std::vector<xgl_testing::Device::Format>::const_iterator it = test_formats_.begin();
         it != test_formats_.end(); it++) {

        // not sure what to do here
        if (it->format == XGL_FMT_UNDEFINED ||
            (it->format >= XGL_FMT_B8G8R8_UNORM &&
             it->format <= XGL_FMT_B8G8R8_SRGB))
            continue;

        XGL_IMAGE_CREATE_INFO img_info = xgl_testing::Image::create_info();
        img_info.imageType = XGL_IMAGE_2D;
        img_info.format = it->format;
        img_info.extent.width = 64;
        img_info.extent.height = 64;
        img_info.tiling = it->tiling;

        test_copy_image_to_memory(img_info);
    }
}

class XglCmdCopyImageTest : public XglCmdBlitImageTest {
protected:
    virtual void SetUp()
    {
        XglCmdBlitTest::SetUp();
        init_test_formats(XGL_FORMAT_IMAGE_COPY_BIT);
        ASSERT_NE(true, test_formats_.empty());
    }

    void test_copy_image(const XGL_IMAGE_CREATE_INFO &src_info, const XGL_IMAGE_CREATE_INFO &dst_info,
                         const std::vector<XGL_IMAGE_COPY> &copies)
    {
        // convert XGL_IMAGE_COPY to two sets of XGL_BUFFER_IMAGE_COPY
        std::vector<XGL_BUFFER_IMAGE_COPY> src_regions, dst_regions;
        XGL_GPU_SIZE src_offset = 0, dst_offset = 0;
        for (std::vector<XGL_IMAGE_COPY>::const_iterator it = copies.begin(); it != copies.end(); it++) {
            XGL_BUFFER_IMAGE_COPY src_region = {}, dst_region = {};

            src_region.bufferOffset = src_offset;
            src_region.imageSubresource = it->srcSubresource;
            src_region.imageOffset = it->srcOffset;
            src_region.imageExtent = it->extent;
            src_regions.push_back(src_region);

            dst_region.bufferOffset = src_offset;
            dst_region.imageSubresource = it->destSubresource;
            dst_region.imageOffset = it->destOffset;
            dst_region.imageExtent = it->extent;
            dst_regions.push_back(dst_region);

            const XGL_GPU_SIZE size = it->extent.width * it->extent.height * it->extent.depth;
            src_offset += xgl_testing::get_format_size(src_info.format) * size;
            dst_offset += xgl_testing::get_format_size(dst_info.format) * size;
        }

        xgl_testing::ImageChecker src_checker(src_info, src_regions);
        xgl_testing::ImageChecker dst_checker(dst_info, dst_regions);

        xgl_testing::Image src;
        src.init(dev_, src_info);
        fill_src(src, src_checker);
        add_memory_ref(src, XGL_MEMORY_REF_READ_ONLY_BIT);

        xgl_testing::Image dst;
        dst.init(dev_, dst_info);
        add_memory_ref(dst, 0);

        cmd_.begin();
        xglCmdCopyImage(cmd_.obj(), src.obj(), dst.obj(), copies.size(), &copies[0]);
        cmd_.end();

        submit_and_done();

        check_dst(dst, dst_checker);
    }
};

TEST_F(XglCmdCopyImageTest, Basic)
{
    for (std::vector<xgl_testing::Device::Format>::const_iterator it = test_formats_.begin();
         it != test_formats_.end(); it++) {

        // not sure what to do here
        if (it->format == XGL_FMT_UNDEFINED ||
            (it->format >= XGL_FMT_B8G8R8_UNORM &&
             it->format <= XGL_FMT_B8G8R8_SRGB))
            continue;

        XGL_IMAGE_CREATE_INFO img_info = xgl_testing::Image::create_info();
        img_info.imageType = XGL_IMAGE_2D;
        img_info.format = it->format;
        img_info.extent.width = 64;
        img_info.extent.height = 64;
        img_info.tiling = it->tiling;

        XGL_IMAGE_COPY copy = {};
        copy.srcSubresource = xgl_testing::Image::subresource(XGL_IMAGE_ASPECT_COLOR, 0, 0);
        copy.destSubresource = copy.srcSubresource;
        copy.extent = img_info.extent;

        test_copy_image(img_info, img_info, std::vector<XGL_IMAGE_COPY>(&copy, &copy + 1));
    }
}

class XglCmdCloneImageDataTest : public XglCmdBlitImageTest {
protected:
    virtual void SetUp()
    {
        XglCmdBlitTest::SetUp();
        init_test_formats();
        ASSERT_NE(true, test_formats_.empty());
    }

    void test_clone_image_data(const XGL_IMAGE_CREATE_INFO &img_info)
    {
        xgl_testing::ImageChecker checker(img_info);
        xgl_testing::Image src, dst;

        src.init(dev_, img_info);
        if (src.transparent() || src.copyable())
            fill_src(src, checker);
        add_memory_ref(src, XGL_MEMORY_REF_READ_ONLY_BIT);

        dst.init(dev_, img_info);
        add_memory_ref(dst, 0);

        const XGL_IMAGE_LAYOUT layout = XGL_IMAGE_LAYOUT_GENERAL;

        cmd_.begin();
        xglCmdCloneImageData(cmd_.obj(), src.obj(), layout, dst.obj(), layout);
        cmd_.end();

        submit_and_done();

        // cannot verify
        if (!dst.transparent() && !dst.copyable())
            return;

        check_dst(dst, checker);
    }
};

TEST_F(XglCmdCloneImageDataTest, Basic)
{
    for (std::vector<xgl_testing::Device::Format>::const_iterator it = test_formats_.begin();
         it != test_formats_.end(); it++) {
        // not sure what to do here
        if (it->format == XGL_FMT_UNDEFINED ||
            (it->format >= XGL_FMT_R32G32B32_UINT &&
             it->format <= XGL_FMT_R32G32B32_SFLOAT) ||
            (it->format >= XGL_FMT_B8G8R8_UNORM &&
             it->format <= XGL_FMT_B8G8R8_SRGB) ||
            (it->format >= XGL_FMT_BC1_UNORM &&
             it->format <= XGL_FMT_ASTC_12x12_SRGB) ||
            (it->format >= XGL_FMT_D16_UNORM &&
             it->format <= XGL_FMT_D32_SFLOAT_S8_UINT) ||
            it->format == XGL_FMT_R64G64B64_SFLOAT ||
            it->format == XGL_FMT_R64G64B64A64_SFLOAT)
            continue;

        XGL_IMAGE_CREATE_INFO img_info = xgl_testing::Image::create_info();
        img_info.imageType = XGL_IMAGE_2D;
        img_info.format = it->format;
        img_info.extent.width = 64;
        img_info.extent.height = 64;
        img_info.tiling = it->tiling;
        img_info.flags = XGL_IMAGE_CREATE_CLONEABLE_BIT;

        const XGL_IMAGE_SUBRESOURCE_RANGE range =
            xgl_testing::Image::subresource_range(img_info, XGL_IMAGE_ASPECT_COLOR);
        std::vector<XGL_IMAGE_SUBRESOURCE_RANGE> ranges(&range, &range + 1);

        test_clone_image_data(img_info);
    }
}

class XglCmdClearColorImageTest : public XglCmdBlitImageTest {
protected:
    XglCmdClearColorImageTest() : test_raw_(false) {}
    XglCmdClearColorImageTest(bool test_raw) : test_raw_(test_raw) {}

    virtual void SetUp()
    {
        XglCmdBlitTest::SetUp();

        if (test_raw_)
            init_test_formats();
        else
            init_test_formats(XGL_FORMAT_CONVERSION_BIT);

        ASSERT_NE(true, test_formats_.empty());
    }

    union Color {
        float color[4];
        uint32_t raw[4];
    };

    bool test_raw_;

    std::vector<uint8_t> color_to_raw(XGL_FORMAT format, const float color[4])
    {
        std::vector<uint8_t> raw;

        // TODO support all formats
        switch (format) {
        case XGL_FMT_R8G8B8A8_UNORM:
            raw.push_back(color[0] * 255.0f);
            raw.push_back(color[1] * 255.0f);
            raw.push_back(color[2] * 255.0f);
            raw.push_back(color[3] * 255.0f);
            break;
        case XGL_FMT_B8G8R8A8_UNORM:
            raw.push_back(color[2] * 255.0f);
            raw.push_back(color[1] * 255.0f);
            raw.push_back(color[0] * 255.0f);
            raw.push_back(color[3] * 255.0f);
            break;
        default:
            break;
        }

        return raw;
    }

    std::vector<uint8_t> color_to_raw(XGL_FORMAT format, const uint32_t color[4])
    {
        std::vector<uint8_t> raw;

        // TODO support all formats
        switch (format) {
        case XGL_FMT_R8G8B8A8_UNORM:
            raw.push_back(static_cast<uint8_t>(color[0]));
            raw.push_back(static_cast<uint8_t>(color[1]));
            raw.push_back(static_cast<uint8_t>(color[2]));
            raw.push_back(static_cast<uint8_t>(color[3]));
            break;
        case XGL_FMT_B8G8R8A8_UNORM:
            raw.push_back(static_cast<uint8_t>(color[2]));
            raw.push_back(static_cast<uint8_t>(color[1]));
            raw.push_back(static_cast<uint8_t>(color[0]));
            raw.push_back(static_cast<uint8_t>(color[3]));
            break;
        default:
            break;
        }

        return raw;
    }

    std::vector<uint8_t> color_to_raw(XGL_FORMAT format, const Color &color)
    {
        if (test_raw_)
            return color_to_raw(format, color.raw);
        else
            return color_to_raw(format, color.color);
    }

    void test_clear_color_image(const XGL_IMAGE_CREATE_INFO &img_info,
                                const Color &color,
                                const std::vector<XGL_IMAGE_SUBRESOURCE_RANGE> &ranges)
    {
        xgl_testing::Image img;
        img.init(dev_, img_info);
        add_memory_ref(img, 0);
        const XGL_FLAGS all_cache_outputs =
                XGL_MEMORY_OUTPUT_CPU_WRITE_BIT |
                XGL_MEMORY_OUTPUT_SHADER_WRITE_BIT |
                XGL_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT |
                XGL_MEMORY_OUTPUT_DEPTH_STENCIL_ATTACHMENT_BIT |
                XGL_MEMORY_OUTPUT_COPY_BIT;
        const XGL_FLAGS all_cache_inputs =
                XGL_MEMORY_INPUT_CPU_READ_BIT |
                XGL_MEMORY_INPUT_INDIRECT_COMMAND_BIT |
                XGL_MEMORY_INPUT_INDEX_FETCH_BIT |
                XGL_MEMORY_INPUT_VERTEX_ATTRIBUTE_FETCH_BIT |
                XGL_MEMORY_INPUT_UNIFORM_READ_BIT |
                XGL_MEMORY_INPUT_SHADER_READ_BIT |
                XGL_MEMORY_INPUT_COLOR_ATTACHMENT_BIT |
                XGL_MEMORY_INPUT_DEPTH_STENCIL_ATTACHMENT_BIT |
                XGL_MEMORY_INPUT_COPY_BIT;

        std::vector<XGL_IMAGE_MEMORY_BARRIER> to_clear;
        std::vector<XGL_IMAGE_MEMORY_BARRIER *> p_to_clear;
        std::vector<XGL_IMAGE_MEMORY_BARRIER> to_xfer;
        std::vector<XGL_IMAGE_MEMORY_BARRIER *> p_to_xfer;

        for (std::vector<XGL_IMAGE_SUBRESOURCE_RANGE>::const_iterator it = ranges.begin();
             it != ranges.end(); it++) {
            to_clear.push_back(img.image_memory_barrier(all_cache_outputs, all_cache_inputs,
                    XGL_IMAGE_LAYOUT_GENERAL,
                    XGL_IMAGE_LAYOUT_CLEAR_OPTIMAL,
                    *it));
            p_to_clear.push_back(&to_clear.back());
            to_xfer.push_back(img.image_memory_barrier(all_cache_outputs, all_cache_inputs,
                    XGL_IMAGE_LAYOUT_CLEAR_OPTIMAL,
                    XGL_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, *it));
            p_to_xfer.push_back(&to_xfer.back());
        }

        cmd_.begin();

        XGL_SET_EVENT set_events[] = { XGL_SET_EVENT_GPU_COMMANDS_COMPLETE };
        XGL_PIPELINE_BARRIER pipeline_barrier = {};
        pipeline_barrier.sType = XGL_STRUCTURE_TYPE_PIPELINE_BARRIER;
        pipeline_barrier.eventCount = 1;
        pipeline_barrier.pEvents = set_events;
        pipeline_barrier.waitEvent = XGL_WAIT_EVENT_TOP_OF_PIPE;
        pipeline_barrier.memBarrierCount = to_clear.size();
        pipeline_barrier.pMemBarriers = (const void **)&p_to_clear[0];
        xglCmdPipelineBarrier(cmd_.obj(), &pipeline_barrier);

        if (test_raw_) {
            xglCmdClearColorImageRaw(cmd_.obj(), img.obj(), color.raw, ranges.size(), &ranges[0]);
        } else {
            xglCmdClearColorImage(cmd_.obj(), img.obj(), color.color, ranges.size(), &ranges[0]);
        }

        pipeline_barrier.sType = XGL_STRUCTURE_TYPE_PIPELINE_BARRIER;
        pipeline_barrier.eventCount = 1;
        pipeline_barrier.pEvents = set_events;
        pipeline_barrier.waitEvent = XGL_WAIT_EVENT_TOP_OF_PIPE;
        pipeline_barrier.memBarrierCount = to_xfer.size();
        pipeline_barrier.pMemBarriers = (const void **)&p_to_xfer[0];
        xglCmdPipelineBarrier(cmd_.obj(), &pipeline_barrier);

        cmd_.end();

        submit_and_done();

        // cannot verify
        if (!img.transparent() && !img.copyable())
            return;

        xgl_testing::ImageChecker checker(img_info, ranges);

        const std::vector<uint8_t> solid_pattern = color_to_raw(img_info.format, color);
        if (solid_pattern.empty())
            return;

        checker.set_solid_pattern(solid_pattern);
        check_dst(img, checker);
    }

    void test_clear_color_image(const XGL_IMAGE_CREATE_INFO &img_info,
                                const float color[4],
                                const std::vector<XGL_IMAGE_SUBRESOURCE_RANGE> &ranges)
    {
        Color c;
        memcpy(c.color, color, sizeof(c.color));
        test_clear_color_image(img_info, c, ranges);
    }
};

TEST_F(XglCmdClearColorImageTest, Basic)
{
    for (std::vector<xgl_testing::Device::Format>::const_iterator it = test_formats_.begin();
         it != test_formats_.end(); it++) {
        const float color[4] = { 0.0f, 1.0f, 0.0f, 1.0f };

        XGL_IMAGE_CREATE_INFO img_info = xgl_testing::Image::create_info();
        img_info.imageType = XGL_IMAGE_2D;
        img_info.format = it->format;
        img_info.extent.width = 64;
        img_info.extent.height = 64;
        img_info.tiling = it->tiling;

        const XGL_IMAGE_SUBRESOURCE_RANGE range =
            xgl_testing::Image::subresource_range(img_info, XGL_IMAGE_ASPECT_COLOR);
        std::vector<XGL_IMAGE_SUBRESOURCE_RANGE> ranges(&range, &range + 1);

        test_clear_color_image(img_info, color, ranges);
    }
}

class XglCmdClearColorImageRawTest : public XglCmdClearColorImageTest {
protected:
    XglCmdClearColorImageRawTest() : XglCmdClearColorImageTest(true) {}

    void test_clear_color_image_raw(const XGL_IMAGE_CREATE_INFO &img_info,
                                    const uint32_t color[4],
                                    const std::vector<XGL_IMAGE_SUBRESOURCE_RANGE> &ranges)
    {
        Color c;
        memcpy(c.raw, color, sizeof(c.raw));
        test_clear_color_image(img_info, c, ranges);
    }
};

TEST_F(XglCmdClearColorImageRawTest, Basic)
{
    for (std::vector<xgl_testing::Device::Format>::const_iterator it = test_formats_.begin();
         it != test_formats_.end(); it++) {
        const uint32_t color[4] = { 0x11111111, 0x22222222, 0x33333333, 0x44444444 };

        // not sure what to do here
        if (it->format == XGL_FMT_UNDEFINED ||
            (it->format >= XGL_FMT_R8G8B8_UNORM &&
             it->format <= XGL_FMT_R8G8B8_SRGB) ||
            (it->format >= XGL_FMT_B8G8R8_UNORM &&
             it->format <= XGL_FMT_B8G8R8_SRGB) ||
            (it->format >= XGL_FMT_R16G16B16_UNORM &&
             it->format <= XGL_FMT_R16G16B16_SFLOAT) ||
            (it->format >= XGL_FMT_R32G32B32_UINT &&
             it->format <= XGL_FMT_R32G32B32_SFLOAT) ||
            it->format == XGL_FMT_R64G64B64_SFLOAT ||
            it->format == XGL_FMT_R64G64B64A64_SFLOAT ||
            (it->format >= XGL_FMT_D16_UNORM &&
             it->format <= XGL_FMT_D32_SFLOAT_S8_UINT))
            continue;

        XGL_IMAGE_CREATE_INFO img_info = xgl_testing::Image::create_info();
        img_info.imageType = XGL_IMAGE_2D;
        img_info.format = it->format;
        img_info.extent.width = 64;
        img_info.extent.height = 64;
        img_info.tiling = it->tiling;

        const XGL_IMAGE_SUBRESOURCE_RANGE range =
            xgl_testing::Image::subresource_range(img_info, XGL_IMAGE_ASPECT_COLOR);
        std::vector<XGL_IMAGE_SUBRESOURCE_RANGE> ranges(&range, &range + 1);

        test_clear_color_image_raw(img_info, color, ranges);
    }
}

class XglCmdClearDepthStencilTest : public XglCmdBlitImageTest {
protected:
    virtual void SetUp()
    {
        XglCmdBlitTest::SetUp();
        init_test_formats(XGL_FORMAT_DEPTH_ATTACHMENT_BIT |
                          XGL_FORMAT_STENCIL_ATTACHMENT_BIT);
        ASSERT_NE(true, test_formats_.empty());
    }

    std::vector<uint8_t> ds_to_raw(XGL_FORMAT format, float depth, uint32_t stencil)
    {
        std::vector<uint8_t> raw;

        // depth
        switch (format) {
        case XGL_FMT_D16_UNORM:
        case XGL_FMT_D16_UNORM_S8_UINT:
            {
                const uint16_t unorm = depth * 65535.0f;
                raw.push_back(unorm & 0xff);
                raw.push_back(unorm >> 8);
            }
            break;
        case XGL_FMT_D32_SFLOAT:
        case XGL_FMT_D32_SFLOAT_S8_UINT:
            {
                const union {
                    float depth;
                    uint32_t u32;
                } u = { depth };

                raw.push_back((u.u32      ) & 0xff);
                raw.push_back((u.u32 >>  8) & 0xff);
                raw.push_back((u.u32 >> 16) & 0xff);
                raw.push_back((u.u32 >> 24) & 0xff);
            }
            break;
        default:
            break;
        }

        // stencil
        switch (format) {
        case XGL_FMT_S8_UINT:
            raw.push_back(stencil);
            break;
        case XGL_FMT_D16_UNORM_S8_UINT:
            raw.push_back(stencil);
            raw.push_back(0);
            break;
        case XGL_FMT_D32_SFLOAT_S8_UINT:
            raw.push_back(stencil);
            raw.push_back(0);
            raw.push_back(0);
            raw.push_back(0);
            break;
        default:
            break;
        }

        return raw;
    }

    void test_clear_depth_stencil(const XGL_IMAGE_CREATE_INFO &img_info,
                                  float depth, uint32_t stencil,
                                  const std::vector<XGL_IMAGE_SUBRESOURCE_RANGE> &ranges)
    {
        xgl_testing::Image img;
        img.init(dev_, img_info);
        add_memory_ref(img, 0);
        const XGL_FLAGS all_cache_outputs =
                XGL_MEMORY_OUTPUT_CPU_WRITE_BIT |
                XGL_MEMORY_OUTPUT_SHADER_WRITE_BIT |
                XGL_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT |
                XGL_MEMORY_OUTPUT_DEPTH_STENCIL_ATTACHMENT_BIT |
                XGL_MEMORY_OUTPUT_COPY_BIT;
        const XGL_FLAGS all_cache_inputs =
                XGL_MEMORY_INPUT_CPU_READ_BIT |
                XGL_MEMORY_INPUT_INDIRECT_COMMAND_BIT |
                XGL_MEMORY_INPUT_INDEX_FETCH_BIT |
                XGL_MEMORY_INPUT_VERTEX_ATTRIBUTE_FETCH_BIT |
                XGL_MEMORY_INPUT_UNIFORM_READ_BIT |
                XGL_MEMORY_INPUT_SHADER_READ_BIT |
                XGL_MEMORY_INPUT_COLOR_ATTACHMENT_BIT |
                XGL_MEMORY_INPUT_DEPTH_STENCIL_ATTACHMENT_BIT |
                XGL_MEMORY_INPUT_COPY_BIT;

        std::vector<XGL_IMAGE_MEMORY_BARRIER> to_clear;
        std::vector<XGL_IMAGE_MEMORY_BARRIER *> p_to_clear;
        std::vector<XGL_IMAGE_MEMORY_BARRIER> to_xfer;
        std::vector<XGL_IMAGE_MEMORY_BARRIER *> p_to_xfer;

        for (std::vector<XGL_IMAGE_SUBRESOURCE_RANGE>::const_iterator it = ranges.begin();
             it != ranges.end(); it++) {
            to_clear.push_back(img.image_memory_barrier(all_cache_outputs, all_cache_inputs,
                    XGL_IMAGE_LAYOUT_GENERAL,
                    XGL_IMAGE_LAYOUT_CLEAR_OPTIMAL,
                    *it));
            p_to_clear.push_back(&to_clear.back());
            to_xfer.push_back(img.image_memory_barrier(all_cache_outputs, all_cache_inputs,
                    XGL_IMAGE_LAYOUT_CLEAR_OPTIMAL,
                    XGL_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, *it));
            p_to_xfer.push_back(&to_xfer.back());
        }

        cmd_.begin();

        XGL_SET_EVENT set_events[] = { XGL_SET_EVENT_GPU_COMMANDS_COMPLETE };
        XGL_PIPELINE_BARRIER pipeline_barrier = {};
        pipeline_barrier.sType = XGL_STRUCTURE_TYPE_PIPELINE_BARRIER;
        pipeline_barrier.eventCount = 1;
        pipeline_barrier.pEvents = set_events;
        pipeline_barrier.waitEvent = XGL_WAIT_EVENT_TOP_OF_PIPE;
        pipeline_barrier.memBarrierCount = to_clear.size();
        pipeline_barrier.pMemBarriers = (const void **)&p_to_clear[0];
        xglCmdPipelineBarrier(cmd_.obj(), &pipeline_barrier);

        xglCmdClearDepthStencil(cmd_.obj(), img.obj(), depth, stencil, ranges.size(), &ranges[0]);

        pipeline_barrier.sType = XGL_STRUCTURE_TYPE_PIPELINE_BARRIER;
        pipeline_barrier.eventCount = 1;
        pipeline_barrier.pEvents = set_events;
        pipeline_barrier.waitEvent = XGL_WAIT_EVENT_TOP_OF_PIPE;
        pipeline_barrier.memBarrierCount = to_xfer.size();
        pipeline_barrier.pMemBarriers = (const void **)&p_to_xfer[0];
        xglCmdPipelineBarrier(cmd_.obj(), &pipeline_barrier);

        cmd_.end();

        submit_and_done();

        // cannot verify
        if (!img.transparent() && !img.copyable())
            return;

        xgl_testing::ImageChecker checker(img_info, ranges);

        checker.set_solid_pattern(ds_to_raw(img_info.format, depth, stencil));
        check_dst(img, checker);
    }
};

TEST_F(XglCmdClearDepthStencilTest, Basic)
{
    for (std::vector<xgl_testing::Device::Format>::const_iterator it = test_formats_.begin();
         it != test_formats_.end(); it++) {
        // known driver issues
        if (it->format == XGL_FMT_S8_UINT ||
            it->format == XGL_FMT_D24_UNORM ||
            it->format == XGL_FMT_D16_UNORM_S8_UINT ||
            it->format == XGL_FMT_D24_UNORM_S8_UINT)
            continue;

        XGL_IMAGE_CREATE_INFO img_info = xgl_testing::Image::create_info();
        img_info.imageType = XGL_IMAGE_2D;
        img_info.format = it->format;
        img_info.extent.width = 64;
        img_info.extent.height = 64;
        img_info.tiling = it->tiling;
        img_info.usage = XGL_IMAGE_USAGE_DEPTH_STENCIL_BIT;

        const XGL_IMAGE_SUBRESOURCE_RANGE range =
            xgl_testing::Image::subresource_range(img_info, XGL_IMAGE_ASPECT_DEPTH);
        std::vector<XGL_IMAGE_SUBRESOURCE_RANGE> ranges(&range, &range + 1);

        test_clear_depth_stencil(img_info, 0.25f, 63, ranges);
    }
}

}; // namespace

int main(int argc, char **argv)
{
    ::testing::InitGoogleTest(&argc, argv);

    xgl_testing::set_error_callback(test_error_callback);

    environment = new xgl_testing::Environment();

    if (!environment->parse_args(argc, argv))
        return -1;

    ::testing::AddGlobalTestEnvironment(environment);

    return RUN_ALL_TESTS();
}
