// VK 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 "math.h"
#include "test_common.h"
#include "vktestbinding.h"
#include "test_environment.h"

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

namespace vk_testing {

size_t get_format_size(VkFormat format);

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

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

    VkDeviceSize 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<VkBufferImageCopy> &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;
    VkSubresourceLayout buffer_layout(const VkBufferImageCopy &region) const;

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

    std::vector<uint8_t> pattern_hash(const VkImageSubresource &subres, const VkOffset3D &offset) const;

    static uint32_t hash_salt_;

    VkImageCreateInfo info_;
    std::vector<VkBufferImageCopy> regions_;

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


uint32_t ImageChecker::hash_salt_;

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

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

        if (info_.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_BIT) {
            if (info_.format != VK_FORMAT_S8_UINT) {
                region.imageSubresource.aspect = VK_IMAGE_ASPECT_DEPTH;
                regions_.push_back(region);
            }

            if (info_.format == VK_FORMAT_D16_UNORM_S8_UINT ||
                info_.format == VK_FORMAT_D32_SFLOAT_S8_UINT ||
                info_.format == VK_FORMAT_S8_UINT) {
                region.imageSubresource.aspect = VK_IMAGE_ASPECT_STENCIL;
                regions_.push_back(region);
            }
        } else {
            region.imageSubresource.aspect = VK_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 VkDeviceSize 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++) {
                VkBufferImageCopy region = regions_[i];

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

ImageChecker::ImageChecker(const VkImageCreateInfo &info, const std::vector<VkImageSubresourceRange> &ranges)
    : info_(info), regions_(), pattern_(HASH)
{
    VkDeviceSize offset = 0;
    for (std::vector<VkImageSubresourceRange>::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++) {
                VkBufferImageCopy 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 (size_t 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);
}

VkSubresourceLayout ImageChecker::buffer_layout(const VkBufferImageCopy &region) const
{
    VkSubresourceLayout 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;
}

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

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

    return size;
}

bool ImageChecker::walk_region(Action action, const VkBufferImageCopy &region,
                               const VkSubresourceLayout &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;

                VkOffset3D 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 (size_t 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.memory().map();
    if (!data)
        return false;

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

    buf.memory().unmap();

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

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

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

    img.memory().unmap();

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

std::vector<uint8_t> ImageChecker::pattern_hash(const VkImageSubresource &subres, const VkOffset3D &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 (size_t i = 0; i < buffer_cpp(); i++)
        val.push_back(output[i % 4]);

    return val;
}

size_t get_format_size(VkFormat format)
{
    static bool format_table_unverified = true;
    static const struct format_info {
        VkFormat_ format;
        size_t size;
        uint32_t channel_count;
    } format_table[VK_NUM_FORMAT] = {
        { VK_FORMAT_UNDEFINED,             0,  0 },
        { VK_FORMAT_R4G4_UNORM,            1,  2 },
        { VK_FORMAT_R4G4_USCALED,          1,  2 },
        { VK_FORMAT_R4G4B4A4_UNORM,        2,  4 },
        { VK_FORMAT_R4G4B4A4_USCALED,      2,  4 },
        { VK_FORMAT_R5G6B5_UNORM,          2,  3 },
        { VK_FORMAT_R5G6B5_USCALED,        2,  3 },
        { VK_FORMAT_R5G5B5A1_UNORM,        2,  4 },
        { VK_FORMAT_R5G5B5A1_USCALED,      2,  4 },
        { VK_FORMAT_R8_UNORM,              1,  1 },
        { VK_FORMAT_R8_SNORM,              1,  1 },
        { VK_FORMAT_R8_USCALED,            1,  1 },
        { VK_FORMAT_R8_SSCALED,            1,  1 },
        { VK_FORMAT_R8_UINT,               1,  1 },
        { VK_FORMAT_R8_SINT,               1,  1 },
        { VK_FORMAT_R8_SRGB,               1,  1 },
        { VK_FORMAT_R8G8_UNORM,            2,  2 },
        { VK_FORMAT_R8G8_SNORM,            2,  2 },
        { VK_FORMAT_R8G8_USCALED,          2,  2 },
        { VK_FORMAT_R8G8_SSCALED,          2,  2 },
        { VK_FORMAT_R8G8_UINT,             2,  2 },
        { VK_FORMAT_R8G8_SINT,             2,  2 },
        { VK_FORMAT_R8G8_SRGB,             2,  2 },
        { VK_FORMAT_R8G8B8_UNORM,          3,  3 },
        { VK_FORMAT_R8G8B8_SNORM,          3,  3 },
        { VK_FORMAT_R8G8B8_USCALED,        3,  3 },
        { VK_FORMAT_R8G8B8_SSCALED,        3,  3 },
        { VK_FORMAT_R8G8B8_UINT,           3,  3 },
        { VK_FORMAT_R8G8B8_SINT,           3,  3 },
        { VK_FORMAT_R8G8B8_SRGB,           3,  3 },
        { VK_FORMAT_R8G8B8A8_UNORM,        4,  4 },
        { VK_FORMAT_R8G8B8A8_SNORM,        4,  4 },
        { VK_FORMAT_R8G8B8A8_USCALED,      4,  4 },
        { VK_FORMAT_R8G8B8A8_SSCALED,      4,  4 },
        { VK_FORMAT_R8G8B8A8_UINT,         4,  4 },
        { VK_FORMAT_R8G8B8A8_SINT,         4,  4 },
        { VK_FORMAT_R8G8B8A8_SRGB,         4,  4 },
        { VK_FORMAT_R10G10B10A2_UNORM,     4,  4 },
        { VK_FORMAT_R10G10B10A2_SNORM,     4,  4 },
        { VK_FORMAT_R10G10B10A2_USCALED,   4,  4 },
        { VK_FORMAT_R10G10B10A2_SSCALED,   4,  4 },
        { VK_FORMAT_R10G10B10A2_UINT,      4,  4 },
        { VK_FORMAT_R10G10B10A2_SINT,      4,  4 },
        { VK_FORMAT_R16_UNORM,             2,  1 },
        { VK_FORMAT_R16_SNORM,             2,  1 },
        { VK_FORMAT_R16_USCALED,           2,  1 },
        { VK_FORMAT_R16_SSCALED,           2,  1 },
        { VK_FORMAT_R16_UINT,              2,  1 },
        { VK_FORMAT_R16_SINT,              2,  1 },
        { VK_FORMAT_R16_SFLOAT,            2,  1 },
        { VK_FORMAT_R16G16_UNORM,          4,  2 },
        { VK_FORMAT_R16G16_SNORM,          4,  2 },
        { VK_FORMAT_R16G16_USCALED,        4,  2 },
        { VK_FORMAT_R16G16_SSCALED,        4,  2 },
        { VK_FORMAT_R16G16_UINT,           4,  2 },
        { VK_FORMAT_R16G16_SINT,           4,  2 },
        { VK_FORMAT_R16G16_SFLOAT,         4,  2 },
        { VK_FORMAT_R16G16B16_UNORM,       6,  3 },
        { VK_FORMAT_R16G16B16_SNORM,       6,  3 },
        { VK_FORMAT_R16G16B16_USCALED,     6,  3 },
        { VK_FORMAT_R16G16B16_SSCALED,     6,  3 },
        { VK_FORMAT_R16G16B16_UINT,        6,  3 },
        { VK_FORMAT_R16G16B16_SINT,        6,  3 },
        { VK_FORMAT_R16G16B16_SFLOAT,      6,  3 },
        { VK_FORMAT_R16G16B16A16_UNORM,    8,  4 },
        { VK_FORMAT_R16G16B16A16_SNORM,    8,  4 },
        { VK_FORMAT_R16G16B16A16_USCALED,  8,  4 },
        { VK_FORMAT_R16G16B16A16_SSCALED,  8,  4 },
        { VK_FORMAT_R16G16B16A16_UINT,     8,  4 },
        { VK_FORMAT_R16G16B16A16_SINT,     8,  4 },
        { VK_FORMAT_R16G16B16A16_SFLOAT,   8,  4 },
        { VK_FORMAT_R32_UINT,              4,  1 },
        { VK_FORMAT_R32_SINT,              4,  1 },
        { VK_FORMAT_R32_SFLOAT,            4,  1 },
        { VK_FORMAT_R32G32_UINT,           8,  2 },
        { VK_FORMAT_R32G32_SINT,           8,  2 },
        { VK_FORMAT_R32G32_SFLOAT,         8,  2 },
        { VK_FORMAT_R32G32B32_UINT,        12, 3 },
        { VK_FORMAT_R32G32B32_SINT,        12, 3 },
        { VK_FORMAT_R32G32B32_SFLOAT,      12, 3 },
        { VK_FORMAT_R32G32B32A32_UINT,     16, 4 },
        { VK_FORMAT_R32G32B32A32_SINT,     16, 4 },
        { VK_FORMAT_R32G32B32A32_SFLOAT,   16, 4 },
        { VK_FORMAT_R64_SFLOAT,            8,  1 },
        { VK_FORMAT_R64G64_SFLOAT,         16, 2 },
        { VK_FORMAT_R64G64B64_SFLOAT,      24, 3 },
        { VK_FORMAT_R64G64B64A64_SFLOAT,   32, 4 },
        { VK_FORMAT_R11G11B10_UFLOAT,      4,  3 },
        { VK_FORMAT_R9G9B9E5_UFLOAT,       4,  3 },
        { VK_FORMAT_D16_UNORM,             2,  1 },
        { VK_FORMAT_D24_UNORM,             3,  1 },
        { VK_FORMAT_D32_SFLOAT,            4,  1 },
        { VK_FORMAT_S8_UINT,               1,  1 },
        { VK_FORMAT_D16_UNORM_S8_UINT,     3,  2 },
        { VK_FORMAT_D24_UNORM_S8_UINT,     4,  2 },
        { VK_FORMAT_D32_SFLOAT_S8_UINT,    8,  2 },
        { VK_FORMAT_BC1_RGB_UNORM,         8,  4 },
        { VK_FORMAT_BC1_RGB_SRGB,          8,  4 },
        { VK_FORMAT_BC1_RGBA_UNORM,        8,  4 },
        { VK_FORMAT_BC1_RGBA_SRGB,         8,  4 },
        { VK_FORMAT_BC2_UNORM,             16, 4 },
        { VK_FORMAT_BC2_SRGB,              16, 4 },
        { VK_FORMAT_BC3_UNORM,             16, 4 },
        { VK_FORMAT_BC3_SRGB,              16, 4 },
        { VK_FORMAT_BC4_UNORM,             8,  4 },
        { VK_FORMAT_BC4_SNORM,             8,  4 },
        { VK_FORMAT_BC5_UNORM,             16, 4 },
        { VK_FORMAT_BC5_SNORM,             16, 4 },
        { VK_FORMAT_BC6H_UFLOAT,           16, 4 },
        { VK_FORMAT_BC6H_SFLOAT,           16, 4 },
        { VK_FORMAT_BC7_UNORM,             16, 4 },
        { VK_FORMAT_BC7_SRGB,              16, 4 },
        // TODO: Initialize remaining compressed formats.
        { VK_FORMAT_ETC2_R8G8B8_UNORM,     0, 0 },
        { VK_FORMAT_ETC2_R8G8B8_SRGB,      0, 0 },
        { VK_FORMAT_ETC2_R8G8B8A1_UNORM,   0, 0 },
        { VK_FORMAT_ETC2_R8G8B8A1_SRGB,    0, 0 },
        { VK_FORMAT_ETC2_R8G8B8A8_UNORM,   0, 0 },
        { VK_FORMAT_ETC2_R8G8B8A8_SRGB,    0, 0 },
        { VK_FORMAT_EAC_R11_UNORM,         0, 0 },
        { VK_FORMAT_EAC_R11_SNORM,         0, 0 },
        { VK_FORMAT_EAC_R11G11_UNORM,      0, 0 },
        { VK_FORMAT_EAC_R11G11_SNORM,      0, 0 },
        { VK_FORMAT_ASTC_4x4_UNORM,        0, 0 },
        { VK_FORMAT_ASTC_4x4_SRGB,         0, 0 },
        { VK_FORMAT_ASTC_5x4_UNORM,        0, 0 },
        { VK_FORMAT_ASTC_5x4_SRGB,         0, 0 },
        { VK_FORMAT_ASTC_5x5_UNORM,        0, 0 },
        { VK_FORMAT_ASTC_5x5_SRGB,         0, 0 },
        { VK_FORMAT_ASTC_6x5_UNORM,        0, 0 },
        { VK_FORMAT_ASTC_6x5_SRGB,         0, 0 },
        { VK_FORMAT_ASTC_6x6_UNORM,        0, 0 },
        { VK_FORMAT_ASTC_6x6_SRGB,         0, 0 },
        { VK_FORMAT_ASTC_8x5_UNORM,        0, 0 },
        { VK_FORMAT_ASTC_8x5_SRGB,         0, 0 },
        { VK_FORMAT_ASTC_8x6_UNORM,        0, 0 },
        { VK_FORMAT_ASTC_8x6_SRGB,         0, 0 },
        { VK_FORMAT_ASTC_8x8_UNORM,        0, 0 },
        { VK_FORMAT_ASTC_8x8_SRGB,         0, 0 },
        { VK_FORMAT_ASTC_10x5_UNORM,       0, 0 },
        { VK_FORMAT_ASTC_10x5_SRGB,        0, 0 },
        { VK_FORMAT_ASTC_10x6_UNORM,       0, 0 },
        { VK_FORMAT_ASTC_10x6_SRGB,        0, 0 },
        { VK_FORMAT_ASTC_10x8_UNORM,       0, 0 },
        { VK_FORMAT_ASTC_10x8_SRGB,        0, 0 },
        { VK_FORMAT_ASTC_10x10_UNORM,      0, 0 },
        { VK_FORMAT_ASTC_10x10_SRGB,       0, 0 },
        { VK_FORMAT_ASTC_12x10_UNORM,      0, 0 },
        { VK_FORMAT_ASTC_12x10_SRGB,       0, 0 },
        { VK_FORMAT_ASTC_12x12_UNORM,      0, 0 },
        { VK_FORMAT_ASTC_12x12_SRGB,       0, 0 },
        { VK_FORMAT_B4G4R4A4_UNORM,        2, 4 },
        { VK_FORMAT_B5G5R5A1_UNORM,        2, 4 },
        { VK_FORMAT_B5G6R5_UNORM,          2, 3 },
        { VK_FORMAT_B5G6R5_USCALED,        2, 3 },
        { VK_FORMAT_B8G8R8_UNORM,          3, 3 },
        { VK_FORMAT_B8G8R8_SNORM,          3, 3 },
        { VK_FORMAT_B8G8R8_USCALED,        3, 3 },
        { VK_FORMAT_B8G8R8_SSCALED,        3, 3 },
        { VK_FORMAT_B8G8R8_UINT,           3, 3 },
        { VK_FORMAT_B8G8R8_SINT,           3, 3 },
        { VK_FORMAT_B8G8R8_SRGB,           3, 3 },
        { VK_FORMAT_B8G8R8A8_UNORM,        4, 4 },
        { VK_FORMAT_B8G8R8A8_SNORM,        4, 4 },
        { VK_FORMAT_B8G8R8A8_USCALED,      4, 4 },
        { VK_FORMAT_B8G8R8A8_SSCALED,      4, 4 },
        { VK_FORMAT_B8G8R8A8_UINT,         4, 4 },
        { VK_FORMAT_B8G8R8A8_SINT,         4, 4 },
        { VK_FORMAT_B8G8R8A8_SRGB,         4, 4 },
        { VK_FORMAT_B10G10R10A2_UNORM,     4, 4 },
        { VK_FORMAT_B10G10R10A2_SNORM,     4, 4 },
        { VK_FORMAT_B10G10R10A2_USCALED,   4, 4 },
        { VK_FORMAT_B10G10R10A2_SSCALED,   4, 4 },
        { VK_FORMAT_B10G10R10A2_UINT,      4, 4 },
        { VK_FORMAT_B10G10R10A2_SINT,      4, 4 },
    };
    if (format_table_unverified)
    {
        for (unsigned int i = 0; i < VK_NUM_FORMAT; i++)
        {
            assert(format_table[i].format == i);
        }
        format_table_unverified = false;
    }

    return format_table[format].size;
}

VkExtent3D get_mip_level_extent(const VkExtent3D &extent, uint32_t mip_level)
{
    const VkExtent3D 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 vk_testing

namespace {

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

static vk_testing::Environment *environment;

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

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

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

    std::vector<VkDeviceMemory> mem_refs_;
};

typedef VkCmdBlitTest VkCmdFillBufferTest;

TEST_F(VkCmdFillBufferTest, Basic)
{
    vk_testing::Buffer buf;
    VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;

    buf.init_as_dst(dev_, 20, reqs);

    cmd_.begin();
    vkCmdFillBuffer(cmd_.handle(), buf.handle(), 0, 4, 0x11111111);
    vkCmdFillBuffer(cmd_.handle(), buf.handle(), 4, 16, 0x22222222);
    cmd_.end();

    submit_and_done();

    const uint32_t *data = static_cast<const uint32_t *>(buf.memory().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.memory().unmap();
}

TEST_F(VkCmdFillBufferTest, Large)
{
    const VkDeviceSize size = 32 * 1024 * 1024;
    vk_testing::Buffer buf;
    VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;

    buf.init_as_dst(dev_, size, reqs);

    cmd_.begin();
    vkCmdFillBuffer(cmd_.handle(), buf.handle(), 0, size / 2, 0x11111111);
    vkCmdFillBuffer(cmd_.handle(), buf.handle(), size / 2, size / 2, 0x22222222);
    cmd_.end();

    submit_and_done();

    const uint32_t *data = static_cast<const uint32_t *>(buf.memory().map());
    VkDeviceSize 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.memory().unmap();
}

TEST_F(VkCmdFillBufferTest, Overlap)
{
    vk_testing::Buffer buf;
    VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;

    buf.init_as_dst(dev_, 64, reqs);

    cmd_.begin();
    vkCmdFillBuffer(cmd_.handle(), buf.handle(), 0, 48, 0x11111111);
    vkCmdFillBuffer(cmd_.handle(), buf.handle(), 32, 32, 0x22222222);
    cmd_.end();

    submit_and_done();

    const uint32_t *data = static_cast<const uint32_t *>(buf.memory().map());
    VkDeviceSize 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.memory().unmap();
}

TEST_F(VkCmdFillBufferTest, MultiAlignments)
{
    vk_testing::Buffer bufs[9];
    VkDeviceSize size = 4;
    VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;

    cmd_.begin();
    for (int i = 0; i < ARRAY_SIZE(bufs); i++) {
        bufs[i].init_as_dst(dev_, size, reqs);
        vkCmdFillBuffer(cmd_.handle(), bufs[i].handle(), 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].memory().map());
        VkDeviceSize offset;
        for (offset = 0; offset < size; offset += 4)
            EXPECT_EQ(0x11111111, data[offset / 4]) << "Buffser is: " << i << "\n" <<
                                                       "Offset is: " << offset;
        bufs[i].memory().unmap();

        size <<= 1;
    }
}

typedef VkCmdBlitTest VkCmdCopyBufferTest;

TEST_F(VkCmdCopyBufferTest, Basic)
{
    vk_testing::Buffer src, dst;
    VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;

    src.init_as_src(dev_, 4, reqs);
    uint32_t *data = static_cast<uint32_t *>(src.memory().map());
    data[0] = 0x11111111;
    src.memory().unmap();

    dst.init_as_dst(dev_, 4, reqs);

    cmd_.begin();
    VkBufferCopy region = {};
    region.copySize = 4;
    vkCmdCopyBuffer(cmd_.handle(), src.handle(), dst.handle(), 1, &region);
    cmd_.end();

    submit_and_done();

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

TEST_F(VkCmdCopyBufferTest, Large)
{
    const VkDeviceSize size = 32 * 1024 * 1024;
    vk_testing::Buffer src, dst;
    VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;

    src.init_as_src(dev_, size, reqs);
    uint32_t *data = static_cast<uint32_t *>(src.memory().map());
    VkDeviceSize offset;
    for (offset = 0; offset < size; offset += 4)
        data[offset / 4] = offset;
    src.memory().unmap();

    dst.init_as_dst(dev_, size, reqs);

    cmd_.begin();
    VkBufferCopy region = {};
    region.copySize = size;
    vkCmdCopyBuffer(cmd_.handle(), src.handle(), dst.handle(), 1, &region);
    cmd_.end();

    submit_and_done();

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

TEST_F(VkCmdCopyBufferTest, MultiAlignments)
{
    const VkBufferCopy 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 },
    };
    vk_testing::Buffer src, dst;
    VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;

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

    dst.init_as_dst(dev_, 1024, reqs);

    cmd_.begin();
    vkCmdCopyBuffer(cmd_.handle(), src.handle(), dst.handle(), ARRAY_SIZE(regions), regions);
    cmd_.end();

    submit_and_done();

    data = static_cast<uint8_t *>(dst.memory().map());
    for (int i = 0; i < ARRAY_SIZE(regions); i++) {
        const VkBufferCopy &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.memory().unmap();
}

TEST_F(VkCmdCopyBufferTest, RAWHazard)
{
    vk_testing::Buffer bufs[3];
    VkEventCreateInfo event_info;
    VkEvent event;
    VkResult err;
    VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;

    //        typedef struct VkEventCreateInfo_
    //        {
    //            VkStructureType                      sType;      // Must be VK_STRUCTURE_TYPE_EVENT_CREATE_INFO
    //            const void*                          pNext;      // Pointer to next structure
    //            VkFlags                              flags;      // Reserved
    //        } VkEventCreateInfo;
    memset(&event_info, 0, sizeof(event_info));
    event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;

    err = vkCreateEvent(dev_.handle(), &event_info, &event);
    ASSERT_VK_SUCCESS(err);

    err = vkResetEvent(dev_.handle(), event);
    ASSERT_VK_SUCCESS(err);

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

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

    cmd_.begin();

    vkCmdFillBuffer(cmd_.handle(), bufs[0].handle(), 0, 4, 0x11111111);
    // is this necessary?
    VkBufferMemoryBarrier memory_barrier = bufs[0].buffer_memory_barrier(
            VK_MEMORY_OUTPUT_TRANSFER_BIT, VK_MEMORY_INPUT_TRANSFER_BIT, 0, 4);
    VkBufferMemoryBarrier *pmemory_barrier = &memory_barrier;

    VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
    VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
    vkCmdPipelineBarrier(cmd_.handle(), src_stages, dest_stages, false, 1, (const void **)&pmemory_barrier);

    VkBufferCopy region = {};
    region.copySize = 4;
    vkCmdCopyBuffer(cmd_.handle(), bufs[0].handle(), bufs[1].handle(), 1, &region);

    memory_barrier = bufs[1].buffer_memory_barrier(
            VK_MEMORY_OUTPUT_TRANSFER_BIT, VK_MEMORY_INPUT_TRANSFER_BIT, 0, 4);
    pmemory_barrier = &memory_barrier;
    vkCmdPipelineBarrier(cmd_.handle(), src_stages, dest_stages, false, 1, (const void **)&pmemory_barrier);

    vkCmdCopyBuffer(cmd_.handle(), bufs[1].handle(), bufs[2].handle(), 1, &region);

    /* Use vkCmdSetEvent and vkCmdWaitEvents to test them.
     * This could be vkCmdPipelineBarrier.
     */
    vkCmdSetEvent(cmd_.handle(), event, VK_PIPELINE_STAGE_TRANSFER_BIT);

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

    memory_barrier = bufs[1].buffer_memory_barrier(
            VK_MEMORY_OUTPUT_TRANSFER_BIT, VK_MEMORY_INPUT_HOST_READ_BIT, 0, 4);
    pmemory_barrier = &memory_barrier;
    vkCmdWaitEvents(cmd_.handle(), 1, &event, src_stages, dest_stages, 1, (const void **)&pmemory_barrier);

    cmd_.end();

    submit_and_done();

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

    err = vkDestroyEvent(dev_.handle(), event);
    ASSERT_VK_SUCCESS(err);

}

class VkCmdBlitImageTest : public VkCmdBlitTest {
protected:
    void init_test_formats(VkFlags features)
    {
        first_linear_format_ = VK_FORMAT_UNDEFINED;
        first_optimal_format_ = VK_FORMAT_UNDEFINED;

        for (std::vector<vk_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 == VK_IMAGE_TILING_LINEAR &&
                    first_linear_format_ == VK_FORMAT_UNDEFINED)
                    first_linear_format_ = it->format;
                if (it->tiling == VK_IMAGE_TILING_OPTIMAL &&
                    first_optimal_format_ == VK_FORMAT_UNDEFINED)
                    first_optimal_format_ = it->format;
            }
        }
    }

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

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

        ASSERT_EQ(true, img.copyable());

        vk_testing::Buffer in_buf;
        VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;

        in_buf.init_as_src(dev_, checker.buffer_size(), reqs);
        checker.fill(in_buf);

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

        submit_and_done();
    }

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

        ASSERT_EQ(true, img.copyable());

        vk_testing::Buffer out_buf;
        VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
        out_buf.init_as_dst(dev_, checker.buffer_size(), reqs);

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

        submit_and_done();

        DO(checker.check(out_buf));
    }

    std::vector<vk_testing::Device::Format> test_formats_;
    VkFormat first_linear_format_;
    VkFormat first_optimal_format_;
};

class VkCmdCopyBufferToImageTest : public VkCmdBlitImageTest {
protected:
    virtual void SetUp()
    {
        VkCmdBlitTest::SetUp();
        init_test_formats(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
        ASSERT_NE(true, test_formats_.empty());
    }

    void test_copy_memory_to_image(const VkImageCreateInfo &img_info, const vk_testing::ImageChecker &checker)
    {
        vk_testing::Buffer buf;
        vk_testing::Image img;
        VkMemoryPropertyFlags buffer_reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
        VkMemoryPropertyFlags image_reqs =
            (img_info.tiling == VK_IMAGE_TILING_LINEAR)?VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT:0;

        buf.init_as_src(dev_, checker.buffer_size(), buffer_reqs);
        checker.fill(buf);

        img.init(dev_, img_info, image_reqs);

        cmd_.begin();
        vkCmdCopyBufferToImage(cmd_.handle(),
                buf.handle(),
                img.handle(), VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL,
                checker.regions().size(), &checker.regions()[0]);
        cmd_.end();

        submit_and_done();

        check_dst(img, checker);
    }

    void test_copy_memory_to_image(const VkImageCreateInfo &img_info, const std::vector<VkBufferImageCopy> &regions)
    {
        vk_testing::ImageChecker checker(img_info, regions);
        test_copy_memory_to_image(img_info, checker);
    }

    void test_copy_memory_to_image(const VkImageCreateInfo &img_info)
    {
        vk_testing::ImageChecker checker(img_info);
        test_copy_memory_to_image(img_info, checker);
    }
};

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

        // not sure what to do here
        if (it->format == VK_FORMAT_UNDEFINED ||
            (it->format >= VK_FORMAT_B8G8R8_UNORM &&
             it->format <= VK_FORMAT_B8G8R8_SRGB))
            continue;

        VkImageCreateInfo img_info = vk_testing::Image::create_info();
        img_info.imageType = VK_IMAGE_TYPE_2D;
        img_info.format = it->format;
        img_info.extent.width = 64;
        img_info.extent.height = 64;
        img_info.tiling = it->tiling;
        img_info.usage = VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT;

        test_copy_memory_to_image(img_info);
    }
}

class VkCmdCopyImageToBufferTest : public VkCmdBlitImageTest {
protected:
    virtual void SetUp()
    {
        VkCmdBlitTest::SetUp();
        init_test_formats(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
        ASSERT_NE(true, test_formats_.empty());
    }

    void test_copy_image_to_memory(const VkImageCreateInfo &img_info, const vk_testing::ImageChecker &checker)
    {
        vk_testing::Image img;
        vk_testing::Buffer buf;
        VkMemoryPropertyFlags buffer_reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
        VkMemoryPropertyFlags image_reqs =
            (img_info.tiling == VK_IMAGE_TILING_LINEAR)?VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT:0;

        img.init(dev_, img_info, image_reqs);
        fill_src(img, checker);

        buf.init_as_dst(dev_, checker.buffer_size(), buffer_reqs);

        cmd_.begin();
        vkCmdCopyImageToBuffer(cmd_.handle(),
                img.handle(), VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL,
                buf.handle(),
                checker.regions().size(), &checker.regions()[0]);
        cmd_.end();

        submit_and_done();

        checker.check(buf);
    }

    void test_copy_image_to_memory(const VkImageCreateInfo &img_info, const std::vector<VkBufferImageCopy> &regions)
    {
        vk_testing::ImageChecker checker(img_info, regions);
        test_copy_image_to_memory(img_info, checker);
    }

    void test_copy_image_to_memory(const VkImageCreateInfo &img_info)
    {
        vk_testing::ImageChecker checker(img_info);
        test_copy_image_to_memory(img_info, checker);
    }
};

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

        // not sure what to do here
        if (it->format == VK_FORMAT_UNDEFINED ||
            (it->format >= VK_FORMAT_B8G8R8_UNORM &&
             it->format <= VK_FORMAT_B8G8R8_SRGB))
            continue;

        VkImageCreateInfo img_info = vk_testing::Image::create_info();
        img_info.imageType = VK_IMAGE_TYPE_2D;
        img_info.format = it->format;
        img_info.extent.width = 64;
        img_info.extent.height = 64;
        img_info.tiling = it->tiling;
        img_info.usage = VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT;

        test_copy_image_to_memory(img_info);
    }
}

class VkCmdCopyImageTest : public VkCmdBlitImageTest {
protected:
    virtual void SetUp()
    {
        VkCmdBlitTest::SetUp();
        init_test_formats(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
        ASSERT_NE(true, test_formats_.empty());
    }

    void test_copy_image(const VkImageCreateInfo &src_info, const VkImageCreateInfo &dst_info,
                         const std::vector<VkImageCopy> &copies)
    {
        // convert VkImageCopy to two sets of VkBufferImageCopy
        std::vector<VkBufferImageCopy> src_regions, dst_regions;
        VkDeviceSize src_offset = 0, dst_offset = 0;
        for (std::vector<VkImageCopy>::const_iterator it = copies.begin(); it != copies.end(); it++) {
            VkBufferImageCopy 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 VkDeviceSize size = it->extent.width * it->extent.height * it->extent.depth;
            src_offset += vk_testing::get_format_size(src_info.format) * size;
            dst_offset += vk_testing::get_format_size(dst_info.format) * size;
        }

        vk_testing::ImageChecker src_checker(src_info, src_regions);
        vk_testing::ImageChecker dst_checker(dst_info, dst_regions);
        VkMemoryPropertyFlags src_reqs =
            (src_info.tiling == VK_IMAGE_TILING_LINEAR)?VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT:0;
        VkMemoryPropertyFlags dst_reqs =
            (dst_info.tiling == VK_IMAGE_TILING_LINEAR)?VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT:0;



        vk_testing::Image src;
        src.init(dev_, src_info, src_reqs);
        fill_src(src, src_checker);

        vk_testing::Image dst;
        dst.init(dev_, dst_info, dst_reqs);

        cmd_.begin();
        vkCmdCopyImage(cmd_.handle(),
                        src.handle(), VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL,
                        dst.handle(), VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL,
                        copies.size(), &copies[0]);
        cmd_.end();

        submit_and_done();

        check_dst(dst, dst_checker);
    }
};

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

        // not sure what to do here
        if (it->format == VK_FORMAT_UNDEFINED ||
            (it->format >= VK_FORMAT_B8G8R8_UNORM &&
             it->format <= VK_FORMAT_B8G8R8_SRGB))
            continue;

        VkImageCreateInfo img_info = vk_testing::Image::create_info();
        img_info.imageType = VK_IMAGE_TYPE_2D;
        img_info.format = it->format;
        img_info.extent.width = 64;
        img_info.extent.height = 64;
        img_info.tiling = it->tiling;
        img_info.usage = VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT | VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT;

        VkImageCopy copy = {};
        copy.srcSubresource = vk_testing::Image::subresource(VK_IMAGE_ASPECT_COLOR, 0, 0);
        copy.destSubresource = copy.srcSubresource;
        copy.extent = img_info.extent;

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

class VkCmdClearColorImageTest : public VkCmdBlitImageTest {
protected:
    VkCmdClearColorImageTest() {}

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

        init_test_formats(VK_FORMAT_FEATURE_CONVERSION_BIT);

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

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

    std::vector<uint8_t> color_to_raw(VkFormat format, const VkClearColorValue &color)
    {
        std::vector<uint8_t> raw;

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

        return raw;
    }

    void test_clear_color_image(const VkImageCreateInfo &img_info,
                                const VkClearColorValue &clear_color,
                                const std::vector<VkImageSubresourceRange> &ranges)
    {
        vk_testing::Image img;
        VkMemoryPropertyFlags image_reqs =
            (img_info.tiling == VK_IMAGE_TILING_LINEAR)?VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT:0;

        img.init(dev_, img_info, image_reqs);
        const VkFlags all_cache_outputs =
                VK_MEMORY_OUTPUT_HOST_WRITE_BIT |
                VK_MEMORY_OUTPUT_SHADER_WRITE_BIT |
                VK_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT |
                VK_MEMORY_OUTPUT_DEPTH_STENCIL_ATTACHMENT_BIT |
                VK_MEMORY_OUTPUT_TRANSFER_BIT;
        const VkFlags all_cache_inputs =
                VK_MEMORY_INPUT_HOST_READ_BIT |
                VK_MEMORY_INPUT_INDIRECT_COMMAND_BIT |
                VK_MEMORY_INPUT_INDEX_FETCH_BIT |
                VK_MEMORY_INPUT_VERTEX_ATTRIBUTE_FETCH_BIT |
                VK_MEMORY_INPUT_UNIFORM_READ_BIT |
                VK_MEMORY_INPUT_SHADER_READ_BIT |
                VK_MEMORY_INPUT_COLOR_ATTACHMENT_BIT |
                VK_MEMORY_INPUT_DEPTH_STENCIL_ATTACHMENT_BIT |
                VK_MEMORY_INPUT_TRANSFER_BIT;

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

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

        cmd_.begin();

        VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_ALL_GPU_COMMANDS;
        VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_ALL_GPU_COMMANDS;
        vkCmdPipelineBarrier(cmd_.handle(), src_stages, dest_stages, false, 1, (const void **)&p_to_clear[0]);

        vkCmdClearColorImage(cmd_.handle(),
                              img.handle(), VK_IMAGE_LAYOUT_GENERAL,
                              &clear_color, ranges.size(), &ranges[0]);

        vkCmdPipelineBarrier(cmd_.handle(), src_stages, dest_stages, false, 1, (const void **)&p_to_xfer[0]);

        cmd_.end();

        submit_and_done();

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

        vk_testing::ImageChecker checker(img_info, ranges);

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

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

    void test_clear_color_image(const VkImageCreateInfo &img_info,
                                const float color[4],
                                const std::vector<VkImageSubresourceRange> &ranges)
    {
        VkClearColorValue c = {};
        memcpy(c.f32, color, sizeof(c.f32));
        test_clear_color_image(img_info, c, ranges);
    }
};

TEST_F(VkCmdClearColorImageTest, Basic)
{
    for (std::vector<vk_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 };
        VkFormatProperties props;
        VkResult err;

        err = vkGetPhysicalDeviceFormatInfo(dev_.phy().handle(), it->format, &props);
        ASSERT_EQ(err, VK_SUCCESS);

        if (it->tiling == VK_IMAGE_TILING_LINEAR && !(props.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
            continue;

        if (it->tiling == VK_IMAGE_TILING_OPTIMAL && !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
            continue;

        VkImageCreateInfo img_info = vk_testing::Image::create_info();
        img_info.imageType = VK_IMAGE_TYPE_2D;
        img_info.format = it->format;
        img_info.extent.width = 64;
        img_info.extent.height = 64;
        img_info.tiling = it->tiling;
        img_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;

        const VkImageSubresourceRange range =
            vk_testing::Image::subresource_range(img_info, VK_IMAGE_ASPECT_COLOR);
        std::vector<VkImageSubresourceRange> ranges(&range, &range + 1);

        test_clear_color_image(img_info, color, ranges);
    }
}

class VkCmdClearDepthStencilTest : public VkCmdBlitImageTest {
protected:
    virtual void SetUp()
    {
        VkCmdBlitTest::SetUp();
        init_test_formats(VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
        ASSERT_NE(true, test_formats_.empty());
    }

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

        // depth
        switch (format) {
        case VK_FORMAT_D16_UNORM:
        case VK_FORMAT_D16_UNORM_S8_UINT:
            {
                const uint16_t unorm = (uint16_t)roundf(depth * 65535.0f);
                raw.push_back(unorm & 0xff);
                raw.push_back(unorm >> 8);
            }
            break;
        case VK_FORMAT_D32_SFLOAT:
        case VK_FORMAT_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 VK_FORMAT_S8_UINT:
            raw.push_back(stencil);
            break;
        case VK_FORMAT_D16_UNORM_S8_UINT:
            raw.push_back(stencil);
            raw.push_back(0);
            break;
        case VK_FORMAT_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 VkImageCreateInfo &img_info,
                                  float depth, uint32_t stencil,
                                  const std::vector<VkImageSubresourceRange> &ranges)
    {
        vk_testing::Image img;
        VkMemoryPropertyFlags image_reqs =
            (img_info.tiling == VK_IMAGE_TILING_LINEAR)?VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT:0;

        img.init(dev_, img_info, image_reqs);
        const VkFlags all_cache_outputs =
                VK_MEMORY_OUTPUT_HOST_WRITE_BIT |
                VK_MEMORY_OUTPUT_SHADER_WRITE_BIT |
                VK_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT |
                VK_MEMORY_OUTPUT_DEPTH_STENCIL_ATTACHMENT_BIT |
                VK_MEMORY_OUTPUT_TRANSFER_BIT;
        const VkFlags all_cache_inputs =
                VK_MEMORY_INPUT_HOST_READ_BIT |
                VK_MEMORY_INPUT_INDIRECT_COMMAND_BIT |
                VK_MEMORY_INPUT_INDEX_FETCH_BIT |
                VK_MEMORY_INPUT_VERTEX_ATTRIBUTE_FETCH_BIT |
                VK_MEMORY_INPUT_UNIFORM_READ_BIT |
                VK_MEMORY_INPUT_SHADER_READ_BIT |
                VK_MEMORY_INPUT_COLOR_ATTACHMENT_BIT |
                VK_MEMORY_INPUT_DEPTH_STENCIL_ATTACHMENT_BIT |
                VK_MEMORY_INPUT_TRANSFER_BIT;

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

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

        cmd_.begin();

        VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_ALL_GPU_COMMANDS;
        VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_ALL_GPU_COMMANDS;
        vkCmdPipelineBarrier(cmd_.handle(), src_stages, dest_stages, false, to_clear.size(), (const void **)&p_to_clear[0]);

        vkCmdClearDepthStencilImage(cmd_.handle(),
                                    img.handle(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
                                    depth, stencil,
                                    ranges.size(), &ranges[0]);

        vkCmdPipelineBarrier(cmd_.handle(), src_stages, dest_stages, false, to_xfer.size(), (const void **)&p_to_xfer[0]);

        cmd_.end();

        submit_and_done();

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

        vk_testing::ImageChecker checker(img_info, ranges);

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

TEST_F(VkCmdClearDepthStencilTest, Basic)
{
    for (std::vector<vk_testing::Device::Format>::const_iterator it = test_formats_.begin();
         it != test_formats_.end(); it++) {
        VkFormatProperties props;
        VkResult err;

        err = vkGetPhysicalDeviceFormatInfo(dev_.phy().handle(), it->format, &props);
        ASSERT_EQ(err, VK_SUCCESS);

        if (it->tiling == VK_IMAGE_TILING_LINEAR && !(props.linearTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
            continue;

        if (it->tiling == VK_IMAGE_TILING_OPTIMAL && !(props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
            continue;

        // known driver issues
        if (it->format == VK_FORMAT_S8_UINT ||
            it->format == VK_FORMAT_D24_UNORM ||
            it->format == VK_FORMAT_D16_UNORM_S8_UINT ||
            it->format == VK_FORMAT_D24_UNORM_S8_UINT)
            continue;

        VkImageCreateInfo img_info = vk_testing::Image::create_info();
        img_info.imageType = VK_IMAGE_TYPE_2D;
        img_info.format = it->format;
        img_info.extent.width = 64;
        img_info.extent.height = 64;
        img_info.tiling = it->tiling;
        img_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_BIT;

        const VkImageSubresourceRange range =
            vk_testing::Image::subresource_range(img_info, VK_IMAGE_ASPECT_DEPTH);
        std::vector<VkImageSubresourceRange> ranges(&range, &range + 1);

        if (it->format == VK_FORMAT_D32_SFLOAT_S8_UINT ||
            it->format == VK_FORMAT_D16_UNORM_S8_UINT ||
            it->format == VK_FORMAT_D24_UNORM_S8_UINT) {
                const VkImageSubresourceRange range2 =
                    vk_testing::Image::subresource_range(img_info, VK_IMAGE_ASPECT_STENCIL);
                ranges.push_back(range2);
            }


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

}; // namespace

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

    vk_testing::set_error_callback(test_error_callback);

    environment = new vk_testing::Environment();

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

    ::testing::AddGlobalTestEnvironment(environment);

    return RUN_ALL_TESTS();
}
