/*
 * Copyright (c) 2015-2026 The Khronos Group Inc.
 * Copyright (c) 2015-2026 Valve Corporation
 * Copyright (c) 2015-2026 LunarG, Inc.
 * Copyright (c) 2015-2026 Google, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 */

#include "layer_validation_tests.h"
#include "sync_helper.h"

#include "utils/image_utils.h"
#include "pipeline_helper.h"

// A reasonable well supported default VkImageCreateInfo for image creation
VkImageCreateInfo ImageTest::DefaultImageInfo() {
    VkImageCreateInfo ci = vku::InitStructHelper();
    ci.flags = 0;                          // assumably any is supported
    ci.imageType = VK_IMAGE_TYPE_2D;       // any is supported
    ci.format = VK_FORMAT_R8G8B8A8_UNORM;  // has mandatory support for all usages
    ci.extent = {64, 64, 1};               // limit is 256 for 3D, or 4096
    ci.mipLevels = 1;                      // any is supported
    ci.arrayLayers = 1;                    // limit is 256
    ci.samples = VK_SAMPLE_COUNT_1_BIT;    // needs to be 1 if TILING_LINEAR
    // if VK_IMAGE_TILING_LINEAR imageType must be 2D, usage must be TRANSFER, and levels layers samplers all 1
    ci.tiling = VK_IMAGE_TILING_OPTIMAL;
    ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;  // depends on format
    ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    return ci;
}

class PositiveImage : public ImageTest {};

TEST_F(PositiveImage, OwnershipTransfers) {
    TEST_DESCRIPTION("Valid image ownership transfers that shouldn't create errors");
    RETURN_IF_SKIP(Init());

    vkt::Queue* no_gfx_queue = m_device->QueueWithoutCapabilities(VK_QUEUE_GRAPHICS_BIT);
    if (!no_gfx_queue) {
        GTEST_SKIP() << "Required queue not present (non-graphics capable required)";
    } else if ((m_device->Physical().queue_properties_[no_gfx_queue->family_index].queueFlags & VK_QUEUE_TRANSFER_BIT) == 0) {
        GTEST_SKIP() << "Non graphic queue doesn't have transfer bit";
    }

    vkt::CommandPool no_gfx_pool(*m_device, no_gfx_queue->family_index, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
    vkt::CommandBuffer no_gfx_cb(*m_device, no_gfx_pool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

    // Create an "exclusive" image owned by the graphics queue.
    VkFlags image_use = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
    vkt::Image image(*m_device, 32, 32, VK_FORMAT_B8G8R8A8_UNORM, image_use);
    auto image_subres = VkImageSubresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};

    VkImageMemoryBarrier image_barrier = vku::InitStructHelper();
    image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
    image_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
    image_barrier.srcQueueFamilyIndex = m_device->graphics_queue_node_index_;
    image_barrier.dstQueueFamilyIndex = no_gfx_queue->family_index;
    image_barrier.image = image;
    image_barrier.subresourceRange = image_subres;

    image.SetLayout(VK_IMAGE_LAYOUT_GENERAL);

    ValidOwnershipTransfer(m_default_queue, m_command_buffer, no_gfx_queue, no_gfx_cb, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
                           VK_PIPELINE_STAGE_TRANSFER_BIT, nullptr, &image_barrier);

    // Change layouts while changing ownership
    image_barrier.srcQueueFamilyIndex = no_gfx_queue->family_index;
    image_barrier.dstQueueFamilyIndex = m_device->graphics_queue_node_index_;
    image_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
    // Make sure the new layout is different from the old
    if (image_barrier.oldLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
        image_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
    } else {
        image_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
    }

    ValidOwnershipTransfer(no_gfx_queue, no_gfx_cb, m_default_queue, m_command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
                           VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, nullptr, &image_barrier);
}

TEST_F(PositiveImage, AliasedMemoryTracking) {
    TEST_DESCRIPTION(
        "Create a buffer, allocate memory, bind memory, destroy the buffer, create an image, and bind the same memory to it");
    RETURN_IF_SKIP(Init());

    VkDeviceSize buff_size = 256;
    auto buffer = std::make_unique<vkt::Buffer>(*m_device, vkt::Buffer::CreateInfo(buff_size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT),
                                                vkt::no_mem);

    VkImageCreateInfo image_create_info = vku::InitStructHelper();
    image_create_info.imageType = VK_IMAGE_TYPE_2D;
    image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;  // mandatory format
    image_create_info.extent = {64, 64, 1};               // at least 4096x4096 is supported
    image_create_info.mipLevels = 1;
    image_create_info.arrayLayers = 1;
    image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
    image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
    image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
    image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
    vkt::Image image(*m_device, image_create_info, vkt::no_mem);

    const auto buffer_memory_requirements = buffer->MemoryRequirements();
    const auto image_memory_requirements = image.MemoryRequirements();

    VkMemoryAllocateInfo alloc_info = vku::InitStructHelper();
    alloc_info.allocationSize = (std::max)(buffer_memory_requirements.size, image_memory_requirements.size);
    bool has_memtype =
        m_device->Physical().SetMemoryType(buffer_memory_requirements.memoryTypeBits & image_memory_requirements.memoryTypeBits,
                                           &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
    if (!has_memtype) {
        GTEST_SKIP() << "Failed to find a host visible memory type for both a buffer and an image";
    }
    vkt::DeviceMemory mem(*m_device, alloc_info);

    auto pData = mem.Map();
    std::memset(pData, 0xCADECADE, static_cast<size_t>(buff_size));
    mem.Unmap();

    buffer->BindMemory(mem, 0);

    // NOW, destroy the buffer. Obviously, the resource no longer occupies this
    // memory. In fact, it was never used by the GPU.
    // Just be sure, wait for idle.
    buffer.reset(nullptr);
    m_device->Wait();

    image.BindMemory(mem, 0);
}

TEST_F(PositiveImage, CreateImageViewFollowsParameterCompatibilityRequirements) {
    TEST_DESCRIPTION("Verify that creating an ImageView with valid usage does not generate validation errors.");
    RETURN_IF_SKIP(Init());
    auto image_ci = vkt::Image::ImageCreateInfo2D(128, 128, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
    image_ci.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
    vkt::Image image(*m_device, image_ci, vkt::set_layout);
    image.CreateView();
}

TEST_F(PositiveImage, BasicUsage) {
    TEST_DESCRIPTION("Verify that we can create a view with usage INPUT_ATTACHMENT");
    RETURN_IF_SKIP(Init());
    vkt::Image image(*m_device, 128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
    vkt::ImageView view = image.CreateView();
}

TEST_F(PositiveImage, FormatCompatibility) {
    TEST_DESCRIPTION("Test format compatibility");
    AddRequiredExtensions(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    VkFormat format = VK_FORMAT_R12X4G12X4_UNORM_2PACK16;

    VkImageFormatListCreateInfo format_list = vku::InitStructHelper();
    format_list.viewFormatCount = 1;
    format_list.pViewFormats = &format;

    VkImageCreateInfo image_create_info = vku::InitStructHelper(&format_list);
    image_create_info.imageType = VK_IMAGE_TYPE_2D;
    image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
    image_create_info.extent = {32, 32, 1};
    image_create_info.mipLevels = 1;
    image_create_info.arrayLayers = 1;
    image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
    image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
    image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
    image_create_info.flags = 0;
    vkt::Image image(*m_device, image_create_info);
}

TEST_F(PositiveImage, MultpilePNext) {
    TEST_DESCRIPTION(
        "Use VkImageFormatListCreateInfo and VkImageCompressionControlEXT to make sure internal "
        "DispatchGetPhysicalDeviceImageFormatProperties2 pass them along");
    SetTargetApiVersion(VK_API_VERSION_1_2);
    AddRequiredExtensions(VK_EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    const VkFormat view_format = VK_FORMAT_R8G8B8A8_UINT;

    VkImageFormatListCreateInfo format_list = vku::InitStructHelper();
    format_list.viewFormatCount = 1;
    format_list.pViewFormats = &view_format;

    VkImageCompressionControlEXT image_compression = vku::InitStructHelper(&format_list);
    image_compression.compressionControlPlaneCount = 0;
    image_compression.flags = VK_IMAGE_COMPRESSION_DEFAULT_EXT;

    VkImageCreateInfo image_create_info = vku::InitStructHelper(&image_compression);
    image_create_info.imageType = VK_IMAGE_TYPE_2D;
    image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
    image_create_info.extent = {32, 32, 1};
    image_create_info.mipLevels = 1;
    image_create_info.arrayLayers = 1;
    image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
    image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
    image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    image_create_info.flags = 0;

    vkt::Image(*m_device, image_create_info);
}

TEST_F(PositiveImage, FramebufferFrom3DImage) {
    TEST_DESCRIPTION("Validate creating a framebuffer from a 3D image.");

    AddRequiredExtensions(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    VkImageCreateInfo image_ci = vku::InitStructHelper();
    image_ci.flags = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
    image_ci.imageType = VK_IMAGE_TYPE_3D;
    image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
    image_ci.extent = {32, 32, 4};
    image_ci.mipLevels = 1;
    image_ci.arrayLayers = 1;
    image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
    image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
    image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    vkt::Image image(*m_device, image_ci, vkt::set_layout);

    VkImageViewCreateInfo dsvci = vku::InitStructHelper();
    dsvci.image = image;
    dsvci.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
    dsvci.format = VK_FORMAT_B8G8R8A8_UNORM;
    dsvci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 4};
    vkt::ImageView view(*m_device, dsvci);

    VkFramebufferCreateInfo fci = vku::InitStructHelper();
    fci.renderPass = m_renderPass;
    fci.attachmentCount = 1;
    fci.pAttachments = &view.handle();
    fci.width = 32;
    fci.height = 32;
    fci.layers = 4;
    vkt::Framebuffer fb(*m_device, fci);
}

TEST_F(PositiveImage, ExtendedUsageWithDifferentFormatViews) {
    TEST_DESCRIPTION("Create views with different formats of an image with extended usage");

    AddRequiredExtensions(VK_KHR_MAINTENANCE_2_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    VkImageCreateInfo image_ci = vku::InitStructHelper();
    image_ci.flags =
        VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_EXTENDED_USAGE_BIT | VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT;
    image_ci.imageType = VK_IMAGE_TYPE_2D;
    image_ci.format = VK_FORMAT_BC3_UNORM_BLOCK;
    image_ci.extent = {
        64,  // width
        64,  // height
        1,   // depth
    };
    image_ci.mipLevels = 1;
    image_ci.arrayLayers = 1;
    image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
    image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
    image_ci.usage =
        VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;

    VkImageFormatProperties image_properties;
    VkResult err = GetImageFormatProps(Gpu(), image_ci, image_properties);
    if (err != VK_SUCCESS) {
        GTEST_SKIP() << "Image format not valid for format, type, tiling, usage and flags combination.";
    }

    vkt::Image image(*m_device, image_ci);
    ASSERT_TRUE(image != VK_NULL_HANDLE);

    // Since the format is compatible with all image's usage, there's no need to restrict usage
    VkImageViewCreateInfo iv_ci = vku::InitStructHelper();
    iv_ci.image = image;
    iv_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
    iv_ci.format = VK_FORMAT_R32G32B32A32_UINT;
    iv_ci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
    vkt::ImageView view(*m_device, iv_ci);
    ASSERT_TRUE(view != VK_NULL_HANDLE);

    // Since usage is inherited from the image, we need to restrict the usage to a subset
    // Compressed images do not support storage, but we want to sample from the compressed
    VkImageViewUsageCreateInfo ivu_ci = vku::InitStructHelper();
    ivu_ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
    iv_ci.pNext = &ivu_ci;
    vkt::ImageView view2(*m_device, iv_ci);
    ASSERT_TRUE(view2 != VK_NULL_HANDLE);
}

TEST_F(PositiveImage, ImageCompressionControl) {
    TEST_DESCRIPTION("Checks for creating fixed rate compression image.");

    SetTargetApiVersion(VK_API_VERSION_1_2);

    AddRequiredExtensions(VK_EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::imageCompressionControl);
    RETURN_IF_SKIP(Init());

    // Query possible image format with vkGetPhysicalDeviceImageFormatProperties2KHR
    VkPhysicalDeviceImageFormatInfo2 image_format_info = vku::InitStructHelper();
    image_format_info.format = VK_FORMAT_R8G8B8A8_UNORM;
    image_format_info.tiling = VK_IMAGE_TILING_LINEAR;
    image_format_info.type = VK_IMAGE_TYPE_2D;
    image_format_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;

    VkImageCompressionPropertiesEXT compression_properties = vku::InitStructHelper();
    VkImageFormatProperties2 image_format_properties = vku::InitStructHelper(&compression_properties);

    vk::GetPhysicalDeviceImageFormatProperties2(Gpu(), &image_format_info, &image_format_properties);

    auto image_ci = vkt::Image::ImageCreateInfo2D(1, 1, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT,
                                                  VK_IMAGE_TILING_LINEAR);

    // Create with disabled image compression
    {
        VkImageCompressionControlEXT compressionControl = vku::InitStructHelper();
        compressionControl.flags = VK_IMAGE_COMPRESSION_DISABLED_EXT;
        image_ci.pNext = &compressionControl;

        vkt::Image image(*m_device, image_ci);
    }

    // Create with default image compression, without fixed rate
    {
        VkImageCompressionControlEXT compressionControl = vku::InitStructHelper();
        compressionControl.flags = VK_IMAGE_COMPRESSION_DEFAULT_EXT;
        image_ci.pNext = &compressionControl;

        vkt::Image image(*m_device, image_ci);
    }

    // Create with fixed rate compression image
    {
        VkImageCompressionControlEXT compressionControl = vku::InitStructHelper();
        compressionControl.flags = VK_IMAGE_COMPRESSION_FIXED_RATE_DEFAULT_EXT;
        image_ci.pNext = &compressionControl;

        vkt::Image image(*m_device, image_ci);
    }

    // Create with fixed rate compression image
    if (compression_properties.imageCompressionFixedRateFlags != VK_IMAGE_COMPRESSION_FIXED_RATE_NONE_EXT) {
        VkImageCompressionFixedRateFlagsEXT supported_compression_fixed_rate = VK_IMAGE_COMPRESSION_FIXED_RATE_NONE_EXT;

        for (uint32_t index = 0; index < 32; index++) {
            if ((compression_properties.imageCompressionFixedRateFlags & (1 << index)) != 0) {
                supported_compression_fixed_rate = (1 << index);
                break;
            }
        }

        ASSERT_TRUE(supported_compression_fixed_rate != VK_IMAGE_COMPRESSION_FIXED_RATE_NONE_EXT);

        VkImageCompressionFixedRateFlagsEXT fixedRageFlags = supported_compression_fixed_rate;
        VkImageCompressionControlEXT compressionControl = vku::InitStructHelper();
        compressionControl.flags = VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT;
        compressionControl.pFixedRateFlags = &fixedRageFlags;
        compressionControl.compressionControlPlaneCount = 1;
        image_ci.pNext = &compressionControl;

        vkt::Image image(*m_device, image_ci);
    }
}

TEST_F(PositiveImage, Create3DImageView) {
    TEST_DESCRIPTION("Create a 3D image view");

    RETURN_IF_SKIP(Init());

    VkImageCreateInfo ci = vku::InitStructHelper();
    ci.imageType = VK_IMAGE_TYPE_3D;
    ci.format = VK_FORMAT_R8G8B8A8_UNORM;
    ci.extent = {32, 32, 8};
    ci.mipLevels = 6;
    ci.arrayLayers = 1;
    ci.samples = VK_SAMPLE_COUNT_1_BIT;
    ci.tiling = VK_IMAGE_TILING_OPTIMAL;
    ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
    ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    vkt::Image image(*m_device, ci, vkt::set_layout);
    vkt::ImageView image_view = image.CreateView(VK_IMAGE_VIEW_TYPE_3D);
}

TEST_F(PositiveImage, SlicedCreateInfo) {
    TEST_DESCRIPTION("Test VkImageViewSlicedCreateInfoEXT");

    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_EXT_IMAGE_SLICED_VIEW_OF_3D_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::imageSlicedViewOf3D);
    RETURN_IF_SKIP(Init());

    VkImageCreateInfo ci = vku::InitStructHelper();
    ci.imageType = VK_IMAGE_TYPE_3D;
    ci.format = VK_FORMAT_R8G8B8A8_UNORM;
    ci.extent = {32, 32, 8};
    ci.mipLevels = 6;
    ci.arrayLayers = 1;
    ci.samples = VK_SAMPLE_COUNT_1_BIT;
    ci.tiling = VK_IMAGE_TILING_OPTIMAL;
    ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
    ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    vkt::Image image(*m_device, ci, vkt::set_layout);

    VkImageViewSlicedCreateInfoEXT sliced_info = vku::InitStructHelper();

    VkImageViewCreateInfo ivci = vku::InitStructHelper(&sliced_info);
    ivci.image = image;
    ivci.viewType = VK_IMAGE_VIEW_TYPE_3D;
    ivci.format = ci.format;
    ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
    ivci.subresourceRange.levelCount = 1;
    ivci.subresourceRange.layerCount = 1;

    auto get_effective_depth = [&]() -> uint32_t {
        return GetEffectiveExtent(ci, ivci.subresourceRange.aspectMask, ivci.subresourceRange.baseMipLevel).depth;
    };

    {
        sliced_info.sliceCount = VK_REMAINING_3D_SLICES_EXT;
        sliced_info.sliceOffset = 0;
        ivci.subresourceRange.baseMipLevel = 0;
        ASSERT_TRUE(get_effective_depth() == 8);

        vkt::ImageView image_view(*m_device, ivci);
    }

    {
        sliced_info.sliceCount = VK_REMAINING_3D_SLICES_EXT;
        sliced_info.sliceOffset = 1;
        ivci.subresourceRange.baseMipLevel = 0;
        ASSERT_TRUE(get_effective_depth() == 8);

        vkt::ImageView image_view(*m_device, ivci);
    }

    {
        sliced_info.sliceCount = 8;
        sliced_info.sliceOffset = 0;
        ivci.subresourceRange.baseMipLevel = 0;
        ASSERT_TRUE(get_effective_depth() == 8);

        vkt::ImageView image_view(*m_device, ivci);
    }

    {
        sliced_info.sliceCount = 4;
        sliced_info.sliceOffset = 4;
        ivci.subresourceRange.baseMipLevel = 0;
        ASSERT_TRUE(get_effective_depth() == 8);

        vkt::ImageView image_view(*m_device, ivci);
    }

    {
        sliced_info.sliceCount = 4;
        sliced_info.sliceOffset = 0;
        ivci.subresourceRange.baseMipLevel = 1;
        ASSERT_TRUE(get_effective_depth() == 4);

        vkt::ImageView image_view(*m_device, ivci);
    }

    {
        sliced_info.sliceCount = 2;
        sliced_info.sliceOffset = 0;
        ivci.subresourceRange.baseMipLevel = 2;
        ASSERT_TRUE(get_effective_depth() == 2);

        vkt::ImageView image_view(*m_device, ivci);
    }

    {
        sliced_info.sliceCount = VK_REMAINING_3D_SLICES_EXT;
        sliced_info.sliceOffset = 0;
        ivci.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
        ivci.subresourceRange.baseMipLevel = 5;
        ASSERT_TRUE(get_effective_depth() == 1);

        vkt::ImageView image_view(*m_device, ivci);
    }

    {
        sliced_info.sliceCount = VK_REMAINING_3D_SLICES_EXT;
        sliced_info.sliceOffset = 0;
        ivci.subresourceRange.levelCount = 1;
        ivci.subresourceRange.baseMipLevel = 5;
        ASSERT_TRUE(get_effective_depth() == 1);

        vkt::ImageView image_view(*m_device, ivci);
    }
}

TEST_F(PositiveImage, BlockTexelViewCompatibleMultipleLayers) {
    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_KHR_MAINTENANCE_2_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_MAINTENANCE_6_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::maintenance6);
    RETURN_IF_SKIP(Init());

    VkPhysicalDeviceMaintenance6PropertiesKHR maintenance6_props = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(maintenance6_props);
    if (!maintenance6_props.blockTexelViewCompatibleMultipleLayers) {
        GTEST_SKIP() << "blockTexelViewCompatibleMultipleLayers is not enabled";
    }

    VkImageCreateInfo image_create_info = vku::InitStructHelper();
    image_create_info.flags = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT | VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
    image_create_info.imageType = VK_IMAGE_TYPE_2D;
    image_create_info.format = VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
    image_create_info.extent = {32, 32, 1};
    image_create_info.mipLevels = 4;
    image_create_info.arrayLayers = 2;
    image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
    image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
    image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;

    VkFormatProperties image_fmt;
    vk::GetPhysicalDeviceFormatProperties(m_device->Physical(), image_create_info.format, &image_fmt);
    if (!vkt::Image::IsCompatible(*m_device, image_create_info.usage, image_fmt.optimalTilingFeatures)) {
        GTEST_SKIP() << "Image usage and format not compatible on device";
    }
    vkt::Image image(*m_device, image_create_info, vkt::set_layout);

    VkImageViewCreateInfo ivci = vku::InitStructHelper();
    ivci.image = image;
    ivci.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
    ivci.format = VK_FORMAT_R16G16B16A16_UNORM;
    ivci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 2};
    vkt::ImageView view(*m_device, ivci);
}

TEST_F(PositiveImage, ImageFormatListSizeCompatibleUncompressed) {
    AddRequiredExtensions(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_MAINTENANCE_2_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    if (!FormatFeaturesAreSupported(Gpu(), VK_FORMAT_BC3_UNORM_BLOCK, VK_IMAGE_TILING_OPTIMAL,
                                    VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
        GTEST_SKIP() << "Required formats/features not supported";
    }

    const VkFormat formats[1] = {VK_FORMAT_R32G32B32A32_UINT};
    VkImageFormatListCreateInfo format_list = vku::InitStructHelper(nullptr);
    format_list.viewFormatCount = 1;
    format_list.pViewFormats = formats;

    auto image_ci = vkt::Image::ImageCreateInfo2D(128, 128, 1, 1, VK_FORMAT_BC3_UNORM_BLOCK, VK_IMAGE_USAGE_SAMPLED_BIT);
    image_ci.pNext = &format_list;
    image_ci.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT;

    if (!IsImageFormatSupported(Gpu(), image_ci, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
        GTEST_SKIP() << "Image create info not supported on device";
    }

    vkt::Image image(*m_device, image_ci);
}

TEST_F(PositiveImage, ImageFormatListSizeCompatibleCompressed) {
    AddRequiredExtensions(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_MAINTENANCE_2_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    if (!FormatFeaturesAreSupported(Gpu(), VK_FORMAT_BC3_UNORM_BLOCK, VK_IMAGE_TILING_OPTIMAL,
                                    VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
        GTEST_SKIP() << "Required formats/features not supported";
    }

    const VkFormat formats[2] = {VK_FORMAT_BC3_UNORM_BLOCK, VK_FORMAT_BC2_UNORM_BLOCK};
    VkImageFormatListCreateInfo format_list = vku::InitStructHelper(nullptr);
    format_list.viewFormatCount = 2;
    format_list.pViewFormats = formats;

    auto image_ci = vkt::Image::ImageCreateInfo2D(128, 128, 1, 1, VK_FORMAT_BC3_UNORM_BLOCK, VK_IMAGE_USAGE_SAMPLED_BIT);
    image_ci.pNext = &format_list;
    image_ci.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT | VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT;

    if (!IsImageFormatSupported(Gpu(), image_ci, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
        GTEST_SKIP() << "Image create info not supported on device";
    }

    vkt::Image image(*m_device, image_ci);
}

TEST_F(PositiveImage, ImageAlignmentControl) {
    AddRequiredExtensions(VK_MESA_IMAGE_ALIGNMENT_CONTROL_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::imageAlignmentControl);
    RETURN_IF_SKIP(Init());

    const uint32_t alignment = 0x1;
    VkPhysicalDeviceImageAlignmentControlPropertiesMESA props = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(props);
    if (!(props.supportedImageAlignmentMask & alignment)) {
        GTEST_SKIP() << "supportedImageAlignmentMask doesn't support testing alignment";
    }
    VkImageAlignmentControlCreateInfoMESA alignment_control = vku::InitStructHelper();
    alignment_control.maximumRequestedAlignment = alignment;

    VkImageCreateInfo image_create_info = DefaultImageInfo();
    image_create_info.pNext = &alignment_control;
    vkt::Image image(*m_device, image_create_info, vkt::no_mem);
}

TEST_F(PositiveImage, ImageAlignmentControlZero) {
    AddRequiredExtensions(VK_MESA_IMAGE_ALIGNMENT_CONTROL_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::imageAlignmentControl);
    RETURN_IF_SKIP(Init());

    VkImageAlignmentControlCreateInfoMESA alignment_control = vku::InitStructHelper();
    alignment_control.maximumRequestedAlignment = 0;  // Should ignore

    VkImageCreateInfo image_create_info = DefaultImageInfo();
    image_create_info.pNext = &alignment_control;
    vkt::Image image(*m_device, image_create_info, vkt::no_mem);
}

TEST_F(PositiveImage, RemainingMipLevels2DViewOf3D) {
    AddRequiredExtensions(VK_KHR_MAINTENANCE_1_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    VkImageCreateInfo image_ci = vku::InitStructHelper();
    image_ci.flags = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT | VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT;
    image_ci.imageType = VK_IMAGE_TYPE_3D;
    image_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
    image_ci.extent = {32, 32, 2};
    image_ci.mipLevels = 1;
    image_ci.arrayLayers = 1;
    image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
    image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
    image_ci.usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
    image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    vkt::Image image(*m_device, image_ci, vkt::set_layout);

    vkt::ImageView view = image.CreateView(VK_IMAGE_VIEW_TYPE_2D, 0, VK_REMAINING_MIP_LEVELS, 0, 1);
}

TEST_F(PositiveImage, RemainingMipLevelsBlockTexelView) {
    AddRequiredExtensions(VK_KHR_MAINTENANCE_2_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());
    VkImageCreateInfo image_create_info = vku::InitStructHelper();
    image_create_info.flags = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT | VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
    image_create_info.imageType = VK_IMAGE_TYPE_2D;
    image_create_info.format = VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
    image_create_info.extent = {32, 32, 1};
    image_create_info.mipLevels = 1;
    image_create_info.arrayLayers = 2;
    image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
    image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
    image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;

    if (!IsImageFormatSupported(Gpu(), image_create_info, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
        GTEST_SKIP() << "Image create info not compatible on device";
    }
    vkt::Image image(*m_device, image_create_info, vkt::set_layout);

    VkImageViewCreateInfo ivci = vku::InitStructHelper();
    ivci.image = image;
    ivci.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
    ivci.format = VK_FORMAT_R16G16B16A16_UNORM;
    ivci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, 1};
    vkt::ImageView view(*m_device, ivci);
}

TEST_F(PositiveImage, BlitMaintenance8) {
    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredFeature(vkt::Feature::maintenance8);
    AddRequiredExtensions(VK_KHR_MAINTENANCE_8_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    VkFormat format = VK_FORMAT_R32_SFLOAT;  // Need features ..BLIT_SRC_BIT & ..BLIT_DST_BIT

    if (!FormatFeaturesAreSupported(Gpu(), format, VK_IMAGE_TILING_OPTIMAL,
                                    VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT)) {
        GTEST_SKIP() << "No blit feature format support";
    }

    VkImageCreateInfo ci = vku::InitStructHelper();
    ci.imageType = VK_IMAGE_TYPE_3D;
    ci.format = format;
    ci.extent = {64, 64, 8};
    ci.mipLevels = 1;
    ci.arrayLayers = 1;
    ci.samples = VK_SAMPLE_COUNT_1_BIT;
    ci.tiling = VK_IMAGE_TILING_OPTIMAL;
    ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
    vkt::Image image_3d(*m_device, ci);

    ci.imageType = VK_IMAGE_TYPE_2D;
    ci.extent.depth = 1;
    ci.arrayLayers = 4;
    vkt::Image image_2d(*m_device, ci);

    // src is 2D with multiple layers
    VkImageBlit blit_region = {};
    blit_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1};
    blit_region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
    blit_region.srcOffsets[0] = {0, 0, 0};
    blit_region.srcOffsets[1] = {16, 16, 1};
    blit_region.dstOffsets[0] = {32, 32, 0};
    blit_region.dstOffsets[1] = {64, 64, 1};

    m_command_buffer.Begin();
    vk::CmdBlitImage(m_command_buffer, image_2d, VK_IMAGE_LAYOUT_GENERAL, image_3d, VK_IMAGE_LAYOUT_GENERAL, 1, &blit_region,
                     VK_FILTER_NEAREST);
    m_command_buffer.End();
}

TEST_F(PositiveImage, ImageViewIncompatibleFormat) {
    TEST_DESCRIPTION("Tests for VUID-VkImageViewCreateInfo-image-01761");
    // original issue https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/2203
    AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    auto image_ci = vkt::Image::ImageCreateInfo2D(128, 128, 1, 1, VK_FORMAT_R8_UINT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
    image_ci.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
    vkt::Image mutImage(*m_device, image_ci, vkt::set_layout);

    VkImageViewCreateInfo imgViewInfo = vku::InitStructHelper();
    imgViewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
    imgViewInfo.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
    imgViewInfo.image = mutImage;

    // With a identical format, there should be no error
    imgViewInfo.format = image_ci.format;
    vkt::ImageView image_view(*m_device, imgViewInfo);

    vkt::Image mut_compat_image(*m_device, image_ci);

    imgViewInfo.image = mut_compat_image;
    imgViewInfo.format = VK_FORMAT_R8_SINT;  // different, but size compatible
    vkt::ImageView image_view2(*m_device, imgViewInfo);
}

TEST_F(PositiveImage, BlockTexelViewType) {
    TEST_DESCRIPTION(
        "Create Image with VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT and non-compressed format and ImageView with view type "
        "VK_IMAGE_VIEW_TYPE_3D.");

    AddRequiredExtensions(VK_KHR_MAINTENANCE_2_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());
    VkImageCreateInfo image_create_info = vku::InitStructHelper();
    image_create_info.flags = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT | VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
    image_create_info.imageType = VK_IMAGE_TYPE_3D;
    image_create_info.format = VK_FORMAT_BC1_RGBA_SRGB_BLOCK;
    image_create_info.extent = {32, 32, 1};
    image_create_info.mipLevels = 1;
    image_create_info.arrayLayers = 1;
    image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
    image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
    image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;

    if (!IsImageFormatSupported(Gpu(), image_create_info, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
        GTEST_SKIP() << "Image create info not compatible on device";
    }
    vkt::Image image(*m_device, image_create_info, vkt::set_layout);

    VkImageViewCreateInfo ivci = vku::InitStructHelper();
    ivci.image = image;
    ivci.viewType = VK_IMAGE_VIEW_TYPE_3D;
    ivci.format = VK_FORMAT_R16G16B16A16_UNORM;
    ivci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};

    vkt::ImageView image_view(*m_device, ivci);
}

TEST_F(PositiveImage, CornerSampledImageNV) {
    TEST_DESCRIPTION("Test VK_NV_corner_sampled_image.");
    AddRequiredExtensions(VK_NV_CORNER_SAMPLED_IMAGE_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::cornerSampledImage);
    RETURN_IF_SKIP(Init());

    VkImageCreateInfo image_create_info = vku::InitStructHelper();
    image_create_info.imageType = VK_IMAGE_TYPE_2D;
    image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
    image_create_info.extent = {2, 1, 1};
    image_create_info.mipLevels = 1;
    image_create_info.arrayLayers = 1;
    image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
    image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
    image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
    image_create_info.flags = VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV;

    {
        // Valid # of mip levels
        image_create_info.extent = {7, 7, 1};
        image_create_info.mipLevels = 3;  // 3 = ceil(log2(7))
        vkt::Image image(*m_device, image_create_info, vkt::no_mem);
    }
    {
        image_create_info.extent = {8, 8, 1};
        image_create_info.mipLevels = 3;  // 3 = ceil(log2(8))
        vkt::Image image(*m_device, image_create_info, vkt::no_mem);
    }
    {
        image_create_info.extent = {9, 9, 1};
        image_create_info.mipLevels = 3;  // 4 = ceil(log2(9))
        vkt::Image image(*m_device, image_create_info, vkt::no_mem);
    }
}

TEST_F(PositiveImage, ArrayViewAndSparseFlags) {
    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_MAINTENANCE_9_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::sparseBinding);
    AddRequiredFeature(vkt::Feature::maintenance9);
    RETURN_IF_SKIP(Init());

    VkPhysicalDeviceMaintenance9PropertiesKHR maintenance9_props = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(maintenance9_props);
    if (!maintenance9_props.image2DViewOf3DSparse) {
        GTEST_SKIP() << "image2DViewOf3DSparse is not supported";
    }

    VkImageCreateInfo create_info = vku::InitStructHelper();
    create_info.flags = VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT | VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
    create_info.imageType = VK_IMAGE_TYPE_3D;
    create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
    create_info.extent = {32u, 32u, 1u};
    create_info.mipLevels = 1u;
    create_info.arrayLayers = 1u;
    create_info.samples = VK_SAMPLE_COUNT_1_BIT;
    create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
    create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
    create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;

    vkt::Image(*m_device, create_info, vkt::no_mem);
}

TEST_F(PositiveImage, Image3DWith2DArrayCompatIssue) {
    SetTargetApiVersion(VK_API_VERSION_1_1);
    RETURN_IF_SKIP(Init());

    VkImageCreateInfo image_ci = vku::InitStructHelper();
    image_ci.flags = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
    image_ci.imageType = VK_IMAGE_TYPE_3D;
    image_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
    image_ci.extent = {32, 32, 2};
    image_ci.mipLevels = 1;
    image_ci.arrayLayers = 1;
    image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
    image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
    image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
    image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    vkt::Image image(*m_device, image_ci);

    VkImageMemoryBarrier image_memory_barrier = vku::InitStructHelper();
    image_memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
    image_memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
    image_memory_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    image_memory_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
    image_memory_barrier.image = image;
    image_memory_barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, VK_REMAINING_ARRAY_LAYERS};

    m_command_buffer.Begin();
    vk::CmdPipelineBarrier(m_command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0,
                           nullptr, 1, &image_memory_barrier);
    m_command_buffer.End();
}

TEST_F(PositiveImage, ImageView2dOf3dBaseLayer) {
    TEST_DESCRIPTION("https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/10416");
    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_MAINTENANCE_9_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    VkImageCreateInfo image_ci = vku::InitStructHelper();
    image_ci.flags = VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT;
    image_ci.imageType = VK_IMAGE_TYPE_3D;
    image_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
    image_ci.extent = {32u, 32u, 2u};
    image_ci.mipLevels = 1u;
    image_ci.arrayLayers = 1u;
    image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
    image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
    image_ci.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
    image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    vkt::Image image(*m_device, image_ci);
    vkt::ImageView image_view = image.CreateView(VK_IMAGE_VIEW_TYPE_2D, 0u, 1u, 1u, 1u);
}

TEST_F(PositiveImage, FramebufferRemainingArrayLayers) {
    SetTargetApiVersion(VK_API_VERSION_1_1);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    VkImageCreateInfo image_ci = vku::InitStructHelper();
    image_ci.flags = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
    image_ci.imageType = VK_IMAGE_TYPE_3D;
    image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
    image_ci.extent = {32u, 32u, 5u};
    image_ci.mipLevels = 1u;
    image_ci.arrayLayers = 1u;
    image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
    image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
    image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    vkt::Image image(*m_device, image_ci);
    vkt::ImageView image_view = image.CreateView(VK_IMAGE_VIEW_TYPE_2D_ARRAY, 0u, 1u, 2u, VK_REMAINING_ARRAY_LAYERS);

    VkFramebufferCreateInfo fb_ci = vku::InitStructHelper();
    fb_ci.renderPass = m_renderPass;
    fb_ci.attachmentCount = 1u;
    fb_ci.pAttachments = &image_view.handle();
    fb_ci.width = 32u;
    fb_ci.height = 32u;
    fb_ci.layers = 1u;
    vkt::Framebuffer framebuffer(*m_device, fb_ci);
}

TEST_F(PositiveImage, BlockTexelViewLayerCount) {
    TEST_DESCRIPTION("Create view with VK_REMAINING_ARRAY_LAYERS layerCount from CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE image");
    SetTargetApiVersion(VK_API_VERSION_1_1);
    RETURN_IF_SKIP(Init());
    VkImageCreateInfo image_create_info = vku::InitStructHelper();
    image_create_info.flags = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT | VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT |
                              VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
    image_create_info.imageType = VK_IMAGE_TYPE_3D;
    image_create_info.format = VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
    image_create_info.extent = {32, 32, 2};
    image_create_info.mipLevels = 1;
    image_create_info.arrayLayers = 1;
    image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
    image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
    image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;

    if (!IsImageFormatSupported(Gpu(), image_create_info, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
        GTEST_SKIP() << "Image create info not compatible on device";
    }
    vkt::Image image(*m_device, image_create_info);

    VkImageViewCreateInfo image_view_ci = vku::InitStructHelper();
    image_view_ci.image = image;
    image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
    image_view_ci.format = VK_FORMAT_R16G16B16A16_UNORM;
    image_view_ci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 1, VK_REMAINING_ARRAY_LAYERS};

    // Test that VK_REMAINING_ARRAY_LAYERS evaluates to 1
    vkt::ImageView view(*m_device, image_view_ci);
}

TEST_F(PositiveImage, ExtendedFlags) {
    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_KHR_EXTENDED_FLAGS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::extendedFlags);

    RETURN_IF_SKIP(Init());

    VkImageCreateFlags2CreateInfoKHR create_flags = vku::InitStructHelper();
    create_flags.flags = VK_IMAGE_CREATE_2_2D_ARRAY_COMPATIBLE_BIT_KHR;

    VkImageUsageFlags2CreateInfoKHR usage_flags = vku::InitStructHelper(&create_flags);
    usage_flags.usage = VK_IMAGE_USAGE_2_TRANSFER_DST_BIT_KHR | VK_IMAGE_USAGE_2_SAMPLED_BIT_KHR;

    VkImageCreateInfo image_create_ci = vku::InitStructHelper(&usage_flags);
    image_create_ci.imageType = VK_IMAGE_TYPE_3D;
    image_create_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
    image_create_ci.extent = {32u, 32u, 2u};
    image_create_ci.mipLevels = 1u;
    image_create_ci.arrayLayers = 1u;
    image_create_ci.samples = VK_SAMPLE_COUNT_1_BIT;
    image_create_ci.tiling = VK_IMAGE_TILING_OPTIMAL;

    vkt::Image image(*m_device, image_create_ci);

    VkImageViewCreateInfo image_view_ci = vku::InitStructHelper();
    image_view_ci.image = image;
    image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
    image_view_ci.format = image_create_ci.format;
    image_view_ci.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, VK_REMAINING_ARRAY_LAYERS};
    vkt::ImageView view(*m_device, image_view_ci);

    VkBufferUsageFlags2CreateInfo buffer_usage_flags = vku::InitStructHelper();
    buffer_usage_flags.usage = VK_BUFFER_USAGE_2_TRANSFER_SRC_BIT;

    VkBufferCreateInfo buffer_ci = vku::InitStructHelper(&buffer_usage_flags);
    buffer_ci.size = 32u * 32u * 2u * 4u;
    vkt::Buffer buffer(*m_device, buffer_ci, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

    VkBufferImageCopy region = {};
    region.imageSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u};
    region.imageOffset = {0, 0, 0};
    region.imageExtent = {32u, 32u, 2u};

    m_command_buffer.Begin();
    vk::CmdCopyBufferToImage(m_command_buffer, buffer, image, VK_IMAGE_LAYOUT_GENERAL, 1u, &region);
    m_command_buffer.End();
}

TEST_F(PositiveImage, SparsePropertiesExtendedFlags) {
    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_KHR_EXTENDED_FLAGS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::extendedFlags);
    RETURN_IF_SKIP(Init());

    VkImageUsageFlags2CreateInfoKHR usage_flags_2 = vku::InitStructHelper();
    usage_flags_2.usage = VK_IMAGE_USAGE_2_COLOR_ATTACHMENT_BIT_KHR;

    VkPhysicalDeviceSparseImageFormatInfo2 format_info = vku::InitStructHelper(&usage_flags_2);
    format_info.format = VK_FORMAT_R8G8B8A8_UNORM;
    format_info.type = VK_IMAGE_TYPE_2D;
    format_info.samples = VK_SAMPLE_COUNT_1_BIT;
    format_info.usage = 0;
    format_info.tiling = VK_IMAGE_TILING_OPTIMAL;

    uint32_t propertyCount;
    vk::GetPhysicalDeviceSparseImageFormatProperties2(gpu_, &format_info, &propertyCount, nullptr);
}

TEST_F(PositiveImage, ImageSingleLayerDescriptorFlagButMultiplanarImageView) {
    AddRequiredExtensions(VK_KHR_MAINTENANCE_11_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::maintenance11);
    SetTargetApiVersion(VK_API_VERSION_1_3);
    RETURN_IF_SKIP(Init());

    auto image_ci =
        vkt::Image::ImageCreateInfo2D(128, 128, 1, 1, VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
    image_ci.flags |= VK_IMAGE_CREATE_ALIAS_SINGLE_LAYER_DESCRIPTOR_BIT_KHR | VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;

    VkImageFormatProperties props;
    if (VK_SUCCESS != GetImageFormatProps(Gpu(), image_ci, props)) {
        GTEST_SKIP() << "Image not supported";
    }

    vkt::Image image(*m_device, image_ci);
    VkImageViewCreateInfo image_view_ci = vku::InitStructHelper();
    image_view_ci.image = image;
    image_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D;
    image_view_ci.format = VK_FORMAT_R8_UNORM;
    image_view_ci.subresourceRange = {VK_IMAGE_ASPECT_PLANE_0_BIT, 0u, 1u, 0u, VK_REMAINING_ARRAY_LAYERS};
    vkt::ImageView view(*m_device, image_view_ci);
}

TEST_F(PositiveImage, ImageSampleWeightedInstruction) {
    TEST_DESCRIPTION("Launch a compute pass with an OpImageSampleWeightedQCOM instruction.");
    SetTargetApiVersion(VK_API_VERSION_1_3);
    AddRequiredExtensions(VK_QCOM_IMAGE_PROCESSING_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::textureSampleWeighted);
    RETURN_IF_SKIP(Init());

    VkPhysicalDeviceImageProcessingPropertiesQCOM image_processing_props = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(image_processing_props);

    VkFormat sampled_format = VK_FORMAT_UNDEFINED;
    VkFormat weight_format = VK_FORMAT_UNDEFINED;
    for (VkFormat format : { VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R16G16_UNORM }) {
        const auto format_features2 = m_device->FormatFeaturesOptimal(format);
        if ((format_features2 & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT) != 0 &&
            (format_features2 & VK_FORMAT_FEATURE_2_WEIGHT_SAMPLED_IMAGE_BIT_QCOM) != 0) {
            sampled_format = format;
            break;
        }
    }
    for (VkFormat format : { VK_FORMAT_R16_SFLOAT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R8_UNORM }) {
        const auto format_features2 = m_device->FormatFeaturesOptimal(format);
        if ((format_features2 & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT) != 0 &&
            (format_features2 & VK_FORMAT_FEATURE_2_WEIGHT_IMAGE_BIT_QCOM) != 0) {
            weight_format = format;
            break;
        }
    }

    if ((sampled_format == VK_FORMAT_UNDEFINED) || (weight_format == VK_FORMAT_UNDEFINED)) {
        GTEST_SKIP() << "Failed to find any format that supports VK_FORMAT_FEATURE_2_WEIGHT_SAMPLED_IMAGE_BIT_QCOM "
                        "or VK_FORMAT_FEATURE_2_WEIGHT_IMAGE_BIT_QCOM format feature, skipping test.";
    }

    VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
    sampler_ci.flags = VK_SAMPLER_CREATE_IMAGE_PROCESSING_BIT_QCOM;
    sampler_ci.minLod = 0.0f;
    sampler_ci.maxLod = 0.0f;
    vkt::Sampler sampler{ *m_device, sampler_ci };

    auto image_ci = vkt::Image::ImageCreateInfo2D(512, 512, 1, 1, sampled_format, VK_IMAGE_USAGE_SAMPLED_BIT);
    vkt::Image sampled_image{ *m_device, image_ci };
    vkt::ImageView sampled_image_view = sampled_image.CreateView();

    image_ci.format = weight_format;
    image_ci.usage |= VK_IMAGE_USAGE_SAMPLE_WEIGHT_BIT_QCOM;
    vkt::Image weight_image{ *m_device, image_ci };

    VkImageViewSampleWeightCreateInfoQCOM weight_ci = vku::InitStructHelper();
    weight_ci.filterCenter = { 0, 0 };
    weight_ci.filterSize = image_processing_props.maxWeightFilterDimension;
    weight_ci.numPhases = 1;
    VkImageViewCreateInfo weight_view_ci = vku::InitStructHelper(&weight_ci);
    weight_view_ci.image = weight_image;
    weight_view_ci.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
    weight_view_ci.format = weight_format;
    weight_view_ci.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
    vkt::ImageView weight_image_view{ *m_device, weight_view_ci };

    const char* cs_source = R"glsl(
        #version 460

        #extension GL_QCOM_image_processing: require

        layout(set = 0, binding = 0) uniform texture2D sampled_tex;
        layout(set = 0, binding = 1) uniform texture2DArray weight_tex;
        layout(set = 0, binding = 2) uniform sampler processing_sampler;
        layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

        void main() {
            vec4 result = textureWeightedQCOM(
                sampler2D(sampled_tex, processing_sampler),
                vec2(0.5, 0.5),
                sampler2DArray(weight_tex, processing_sampler)
            );
        }
    )glsl";

    CreateComputePipelineHelper compute_pipe{ *this };
    compute_pipe.cs_ = VkShaderObj{ *m_device, cs_source, VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_3 };
    compute_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr},
                                  {1, VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM, 1, VK_SHADER_STAGE_ALL, nullptr},
                                  {2, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr}};
    compute_pipe.CreateComputePipeline();
    compute_pipe.descriptor_set_.WriteDescriptorImageInfo(0, sampled_image_view, nullptr, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
    compute_pipe.descriptor_set_.WriteDescriptorImageInfo(1, weight_image_view, nullptr, VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM);
    compute_pipe.descriptor_set_.WriteDescriptorImageInfo(2, nullptr, sampler, VK_DESCRIPTOR_TYPE_SAMPLER);
    compute_pipe.descriptor_set_.UpdateDescriptorSets();

    m_command_buffer.Begin();
    vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute_pipe.pipeline_layout_, 0, 1,
                              &compute_pipe.descriptor_set_.set_, 0, nullptr);
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute_pipe);
    vk::CmdDispatch(m_command_buffer, 1, 1, 1);
    m_command_buffer.End();
}

TEST_F(PositiveImage, ImageBoxFilterInstruction) {
    TEST_DESCRIPTION("Launch a compute pass with an OpImageBoxFilterQCOM instruction.");
    SetTargetApiVersion(VK_API_VERSION_1_3);
    AddRequiredExtensions(VK_QCOM_IMAGE_PROCESSING_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::textureBoxFilter);
    RETURN_IF_SKIP(Init());

    VkPhysicalDeviceImageProcessingPropertiesQCOM image_processing_props = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(image_processing_props);

    VkFormat sampled_format = VK_FORMAT_UNDEFINED;
    for (VkFormat format : { VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R16G16_UNORM }) {
        const auto format_features2 = m_device->FormatFeaturesOptimal(format);
        if ((format_features2 & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT) != 0 &&
            (format_features2 & VK_FORMAT_FEATURE_2_BOX_FILTER_SAMPLED_BIT_QCOM) != 0) {
            sampled_format = format;
            break;
        }
    }

    if (sampled_format == VK_FORMAT_UNDEFINED) {
        GTEST_SKIP() << "Failed to find any format that supports VK_FORMAT_FEATURE_2_BOX_FILTER_SAMPLED_BIT_QCOM "
                        "format feature, skipping test.";
    }

    VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
    sampler_ci.flags = VK_SAMPLER_CREATE_IMAGE_PROCESSING_BIT_QCOM;
    sampler_ci.minLod = 0.0f;
    sampler_ci.maxLod = 0.0f;
    vkt::Sampler sampler{ *m_device, sampler_ci };

    const auto image_ci = vkt::Image::ImageCreateInfo2D(512, 512, 1, 1, sampled_format, VK_IMAGE_USAGE_SAMPLED_BIT);
    vkt::Image sampled_image{ *m_device, image_ci };
    vkt::ImageView sampled_image_view = sampled_image.CreateView();

    const char* cs_source = R"glsl(
        #version 460

        #extension GL_QCOM_image_processing: require

        layout(constant_id = 0) const float BOX_SIZE_X = 8.0;
        layout(constant_id = 1) const float BOX_SIZE_Y = 8.0;
        layout(set = 0, binding = 0) uniform texture2D sampled_tex;
        layout(set = 0, binding = 1) uniform sampler processing_sampler;
        layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

        void main() {
            vec4 result = textureBoxFilterQCOM(
                sampler2D(sampled_tex, processing_sampler),
                vec2(0.5, 0.5),
                vec2(BOX_SIZE_X, BOX_SIZE_Y)
            );
        }
    )glsl";

    CreateComputePipelineHelper compute_pipe{ *this };
    constexpr std::array<VkSpecializationMapEntry, 2> map_entries{
        VkSpecializationMapEntry{ 0, 0, sizeof(uint32_t) },
        VkSpecializationMapEntry{ 1, sizeof(uint32_t), sizeof(uint32_t) },
    };
    const std::array<float, 2> box_sizes{
        std::min(8.0f, static_cast<float>(image_processing_props.maxBoxFilterBlockSize.width)),
        std::min(8.0f, static_cast<float>(image_processing_props.maxBoxFilterBlockSize.height)),
    };
    VkSpecializationInfo specialization_info{};
    specialization_info.mapEntryCount = map_entries.size();
    specialization_info.pMapEntries = map_entries.data();
    specialization_info.dataSize = sizeof(box_sizes);
    specialization_info.pData = box_sizes.data();
    compute_pipe.cs_ = VkShaderObj{ *m_device, cs_source, VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_3,
                                    SPV_SOURCE_GLSL, &specialization_info };
    compute_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr},
                                  {1, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr}};
    compute_pipe.CreateComputePipeline();
    compute_pipe.descriptor_set_.WriteDescriptorImageInfo(0, sampled_image_view, nullptr, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
    compute_pipe.descriptor_set_.WriteDescriptorImageInfo(1, nullptr, sampler, VK_DESCRIPTOR_TYPE_SAMPLER);
    compute_pipe.descriptor_set_.UpdateDescriptorSets();

    m_command_buffer.Begin();
    vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute_pipe.pipeline_layout_, 0, 1,
                              &compute_pipe.descriptor_set_.set_, 0, nullptr);
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute_pipe);
    vk::CmdDispatch(m_command_buffer, 1, 1, 1);
    m_command_buffer.End();
}

TEST_F(PositiveImage, ImageBlockMatchInstruction) {
    TEST_DESCRIPTION("Launch a compute pass with an OpImageBlockMatchSADQCOM instruction and "
                     "an OpImageBlockMatchSSDQCOM instruction.");
    SetTargetApiVersion(VK_API_VERSION_1_3);
    AddRequiredExtensions(VK_QCOM_IMAGE_PROCESSING_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::textureBlockMatch);
    RETURN_IF_SKIP(Init());

    VkPhysicalDeviceImageProcessingPropertiesQCOM image_processing_props = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(image_processing_props);

    VkFormat sampled_format = VK_FORMAT_UNDEFINED;
    for (VkFormat format : { VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8_UNORM, VK_FORMAT_R16_UNORM }) {
        const auto format_features2 = m_device->FormatFeaturesOptimal(format);
        if ((format_features2 & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT) != 0 &&
            ((format_features2 & VK_FORMAT_FEATURE_2_BLOCK_MATCHING_BIT_QCOM) != 0 ||
             (format_features2 & VK_FORMAT_FEATURE_2_BLOCK_MATCHING_SXD_BIT_QCOM) != 0)) {
            sampled_format = format;
            break;
        }
    }

    if (sampled_format == VK_FORMAT_UNDEFINED) {
        GTEST_SKIP() << "Failed to find any format that supports VK_FORMAT_FEATURE_2_BLOCK_MATCHING_BIT_QCOM "
                        "or VK_FORMAT_FEATURE_2_BLOCK_MATCHING_SXD_BIT_QCOM format feature, skipping test.";
    }

    VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
    sampler_ci.flags = VK_SAMPLER_CREATE_IMAGE_PROCESSING_BIT_QCOM;
    sampler_ci.minLod = 0.0f;
    sampler_ci.maxLod = 0.0f;
    sampler_ci.unnormalizedCoordinates = VK_TRUE;
    sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
    sampler_ci.addressModeV = sampler_ci.addressModeU;
    sampler_ci.addressModeW = sampler_ci.addressModeU;
    sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
    vkt::Sampler sampler{ *m_device, sampler_ci };

    const auto image_ci = vkt::Image::ImageCreateInfo2D(64, 64, 1, 1, sampled_format,
                                                        VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_SAMPLE_BLOCK_MATCH_BIT_QCOM);
    vkt::Image target_image{ *m_device, image_ci };
    vkt::Image reference_image{ *m_device, image_ci };
    vkt::ImageView target_image_view = target_image.CreateView();
    vkt::ImageView reference_image_view = reference_image.CreateView();

    const char* cs_source = R"glsl(
        #version 460

        #extension GL_QCOM_image_processing: require
        layout(constant_id = 0) const uint BLOCK_SIZE_X = 8;
        layout(constant_id = 1) const uint BLOCK_SIZE_Y = 8;
        layout(set = 0, binding = 0) uniform texture2D target_tex;
        layout(set = 0, binding = 1) uniform texture2D ref_tex;
        layout(set = 0, binding = 2) uniform sampler processing_sampler;
        layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

        void main() {
            uvec2 target_coord = uvec2(0, 0);
            uvec2 ref_coord_1 = uvec2(4, 4);
            uvec2 ref_coord_2 = uvec2(32, 32);
            uvec2 block_size = uvec2(BLOCK_SIZE_X, BLOCK_SIZE_Y);
            vec4 result_1 = textureBlockMatchSADQCOM(
                sampler2D(target_tex, processing_sampler), target_coord,
                sampler2D(ref_tex, processing_sampler), ref_coord_1,
                block_size
            );
            vec4 result_2 = textureBlockMatchSSDQCOM(
                sampler2D(target_tex, processing_sampler), target_coord,
                sampler2D(ref_tex, processing_sampler), ref_coord_2,
                block_size
            );
        }
    )glsl";
    CreateComputePipelineHelper compute_pipe{ *this };
    constexpr std::array<VkSpecializationMapEntry, 2> map_entries{
        VkSpecializationMapEntry{ 0, 0, sizeof(uint32_t) },
        VkSpecializationMapEntry{ 1, sizeof(uint32_t), sizeof(uint32_t) },
    };
    const std::array<uint32_t, 2> block_sizes{
        std::min(8u, image_processing_props.maxBlockMatchRegion.width),
        std::min(8u, image_processing_props.maxBlockMatchRegion.height),
    };
    VkSpecializationInfo specialization_info{};
    specialization_info.mapEntryCount = map_entries.size();
    specialization_info.pMapEntries = map_entries.data();
    specialization_info.dataSize = sizeof(block_sizes);
    specialization_info.pData = block_sizes.data();
    compute_pipe.cs_ = VkShaderObj{ *m_device, cs_source, VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_3,
                                    SPV_SOURCE_GLSL, &specialization_info };
    compute_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM, 1, VK_SHADER_STAGE_ALL, nullptr},
                                  {1, VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM, 1, VK_SHADER_STAGE_ALL, nullptr},
                                  {2, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr}};
    compute_pipe.CreateComputePipeline();
    compute_pipe.descriptor_set_.WriteDescriptorImageInfo(0, target_image_view, nullptr, VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM);
    compute_pipe.descriptor_set_.WriteDescriptorImageInfo(1, reference_image_view, nullptr, VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM);
    compute_pipe.descriptor_set_.WriteDescriptorImageInfo(2, nullptr, sampler, VK_DESCRIPTOR_TYPE_SAMPLER);
    compute_pipe.descriptor_set_.UpdateDescriptorSets();

    m_command_buffer.Begin();
    vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute_pipe.pipeline_layout_, 0, 1,
                              &compute_pipe.descriptor_set_.set_, 0, nullptr);
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute_pipe);
    vk::CmdDispatch(m_command_buffer, 1, 1, 1);
    m_command_buffer.End();
}

TEST_F(PositiveImage, ImageBlockMatchWindowWithClampToEdge) {
    TEST_DESCRIPTION("Launch OpImageBlockMatchWindow*QCOM with both addressModeU and addressModeV set to "
                     "CLAMP_TO_EDGE and blockMatchExtendedClampToEdge feature enabled.");
    SetTargetApiVersion(VK_API_VERSION_1_3);
    AddRequiredExtensions(VK_QCOM_IMAGE_PROCESSING_EXTENSION_NAME);
    AddRequiredExtensions(VK_QCOM_IMAGE_PROCESSING_2_EXTENSION_NAME);
    AddRequiredExtensions(VK_QCOM_IMAGE_PROCESSING_3_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::textureBlockMatch);
    AddRequiredFeature(vkt::Feature::textureBlockMatch2);
    AddRequiredFeature(vkt::Feature::blockMatchExtendedClampToEdge);
    RETURN_IF_SKIP(Init());

    VkPhysicalDeviceImageProcessingPropertiesQCOM image_processing_props = vku::InitStructHelper();
    VkPhysicalDeviceImageProcessing2PropertiesQCOM image_processing2_props = vku::InitStructHelper(&image_processing_props);
    GetPhysicalDeviceProperties2(image_processing2_props);

    VkFormat sampled_format = VK_FORMAT_UNDEFINED;
    for (VkFormat format : {VK_FORMAT_R8_UNORM, VK_FORMAT_R16G16B16A16_UNORM, VK_FORMAT_R8G8B8A8_UNORM}) {
        const auto format_features2 = m_device->FormatFeaturesOptimal(format);
        if ((format_features2 & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT) != 0 &&
            (format_features2 & VK_FORMAT_FEATURE_2_BLOCK_MATCHING_BIT_QCOM) != 0) {
            sampled_format = format;
            break;
        }
    }
    if (sampled_format == VK_FORMAT_UNDEFINED) {
        GTEST_SKIP() << "Failed to find any format that supports VK_FORMAT_FEATURE_2_BLOCK_MATCHING_BIT_QCOM, skipping test.";
    }

    VkSamplerBlockMatchWindowCreateInfoQCOM block_match_window_ci = vku::InitStructHelper();
    block_match_window_ci.windowExtent = image_processing2_props.maxBlockMatchWindow;
    block_match_window_ci.windowCompareMode = VK_BLOCK_MATCH_WINDOW_COMPARE_MODE_MIN_QCOM;
    VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo(&block_match_window_ci);
    sampler_ci.flags = VK_SAMPLER_CREATE_IMAGE_PROCESSING_BIT_QCOM;
    sampler_ci.unnormalizedCoordinates = VK_TRUE;
    sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
    sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
    sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
    sampler_ci.minLod = 0.0f;
    sampler_ci.maxLod = 0.0f;
    vkt::Sampler sampler{*m_device, sampler_ci};

    const auto image_ci = vkt::Image::ImageCreateInfo2D(64, 64, 1, 1, sampled_format,
                                                        VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_SAMPLE_BLOCK_MATCH_BIT_QCOM);
    vkt::Image target_image{*m_device, image_ci};
    vkt::Image reference_image{*m_device, image_ci};
    vkt::ImageView target_image_view = target_image.CreateView();
    vkt::ImageView reference_image_view = reference_image.CreateView();

    const char* cs_source = R"glsl(
        #version 460

        #extension GL_QCOM_image_processing: require
        #extension GL_QCOM_image_processing2: require

        layout(constant_id = 0) const uint BLOCK_SIZE_X = 8;
        layout(constant_id = 1) const uint BLOCK_SIZE_Y = 8;
        layout(set = 0, binding = 0) uniform texture2D target_tex;
        layout(set = 0, binding = 1) uniform texture2D ref_tex;
        layout(set = 0, binding = 2) uniform sampler processing_sampler;
        layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

        void main() {
            uvec2 target_coord = uvec2(0, 0);
            uvec2 ref_coord_1 = uvec2(12, 12);
            uvec2 ref_coord_2 = uvec2(0, 0);
            uvec2 block_size = uvec2(BLOCK_SIZE_X, BLOCK_SIZE_Y);
            vec4 result_1 = textureBlockMatchWindowSSDQCOM(
                sampler2D(target_tex, processing_sampler), target_coord,
                sampler2D(ref_tex, processing_sampler), ref_coord_1,
                block_size
            );
            vec4 result_2 = textureBlockMatchGatherSADQCOM(
                sampler2D(target_tex, processing_sampler), target_coord,
                sampler2D(ref_tex, processing_sampler), ref_coord_2,
                block_size
            );
        }
    )glsl";

    CreateComputePipelineHelper compute_pipe{*this};
    constexpr std::array<VkSpecializationMapEntry, 2> map_entries{
        VkSpecializationMapEntry{0, 0, sizeof(uint32_t)},
        VkSpecializationMapEntry{1, sizeof(uint32_t), sizeof(uint32_t)},
    };
    const std::array<uint32_t, 2> block_sizes{
        std::min(8u, image_processing_props.maxBlockMatchRegion.width),
        std::min(8u, image_processing_props.maxBlockMatchRegion.height),
    };
    VkSpecializationInfo specialization_info{};
    specialization_info.mapEntryCount = map_entries.size();
    specialization_info.pMapEntries = map_entries.data();
    specialization_info.dataSize = sizeof(block_sizes);
    specialization_info.pData = block_sizes.data();
    compute_pipe.cs_ = VkShaderObj{*m_device, cs_source, VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_3,
                                   SPV_SOURCE_GLSL, &specialization_info};
    compute_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM, 1, VK_SHADER_STAGE_ALL, nullptr},
                                  {1, VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM, 1, VK_SHADER_STAGE_ALL, nullptr},
                                  {2, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr}};
    compute_pipe.CreateComputePipeline();
    compute_pipe.descriptor_set_.WriteDescriptorImageInfo(0, target_image_view, nullptr, VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM);
    compute_pipe.descriptor_set_.WriteDescriptorImageInfo(1, reference_image_view, nullptr, VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM);
    compute_pipe.descriptor_set_.WriteDescriptorImageInfo(2, nullptr, sampler, VK_DESCRIPTOR_TYPE_SAMPLER);
    compute_pipe.descriptor_set_.UpdateDescriptorSets();

    m_command_buffer.Begin();
    vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute_pipe.pipeline_layout_, 0, 1,
                              &compute_pipe.descriptor_set_.set_, 0, nullptr);
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute_pipe);
    vk::CmdDispatch(m_command_buffer, 1, 1, 1);
    m_command_buffer.End();
}

TEST_F(PositiveImage, ImageBlockMatchWindowInstruction) {
    TEST_DESCRIPTION("Launch a compute pass with an opImageBlockMatchWindowSSDQCOM instruction and "
                     "an opImageBlockMatchGatherSADQCOM instruction.");
    SetTargetApiVersion(VK_API_VERSION_1_3);
    AddRequiredExtensions(VK_QCOM_IMAGE_PROCESSING_EXTENSION_NAME);
    AddRequiredExtensions(VK_QCOM_IMAGE_PROCESSING_2_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::textureBlockMatch);
    AddRequiredFeature(vkt::Feature::textureBlockMatch2);
    RETURN_IF_SKIP(Init());

    VkPhysicalDeviceImageProcessingPropertiesQCOM image_processing_props = vku::InitStructHelper();
    VkPhysicalDeviceImageProcessing2PropertiesQCOM image_processing2_props = vku::InitStructHelper(&image_processing_props);
    GetPhysicalDeviceProperties2(image_processing2_props);

    VkFormat sampled_format = VK_FORMAT_UNDEFINED;
    for (VkFormat format : { VK_FORMAT_R8_UNORM, VK_FORMAT_R16G16B16A16_UNORM, VK_FORMAT_R8G8B8A8_UNORM }) {
        const auto format_features2 = m_device->FormatFeaturesOptimal(format);
        if ((format_features2 & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT) != 0 &&
            (format_features2 & VK_FORMAT_FEATURE_2_BLOCK_MATCHING_BIT_QCOM) != 0) {
            sampled_format = format;
            break;
        }
    }

    if (sampled_format == VK_FORMAT_UNDEFINED) {
        GTEST_SKIP() << "Failed to find any format that supports VK_FORMAT_FEATURE_2_BLOCK_MATCHING_BIT_QCOM "
                        "format feature, skipping test.";
    }

    VkSamplerBlockMatchWindowCreateInfoQCOM block_match_window_ci = vku::InitStructHelper();
    block_match_window_ci.windowExtent = image_processing2_props.maxBlockMatchWindow;
    block_match_window_ci.windowCompareMode = VK_BLOCK_MATCH_WINDOW_COMPARE_MODE_MIN_QCOM;
    VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo(&block_match_window_ci);
    sampler_ci.flags = VK_SAMPLER_CREATE_IMAGE_PROCESSING_BIT_QCOM;
    sampler_ci.minLod = 0.0f;
    sampler_ci.maxLod = 0.0f;
    sampler_ci.unnormalizedCoordinates = VK_TRUE;
    sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
    sampler_ci.addressModeV = sampler_ci.addressModeU;
    sampler_ci.addressModeW = sampler_ci.addressModeU;
    sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
    vkt::Sampler sampler{ *m_device, sampler_ci };

    const auto image_ci = vkt::Image::ImageCreateInfo2D(64, 64, 1, 1, sampled_format,
                                                        VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_SAMPLE_BLOCK_MATCH_BIT_QCOM);
    vkt::Image target_image{ *m_device, image_ci };
    vkt::Image reference_image{ *m_device, image_ci };
    vkt::ImageView target_image_view = target_image.CreateView();
    vkt::ImageView reference_image_view = reference_image.CreateView();

    const char* cs_source = R"glsl(
        #version 460

        #extension GL_QCOM_image_processing: require
        #extension GL_QCOM_image_processing2: require

        layout(constant_id = 0) const uint BLOCK_SIZE_X = 8;
        layout(constant_id = 1) const uint BLOCK_SIZE_Y = 8;
        layout(set = 0, binding = 0) uniform texture2D target_tex;
        layout(set = 0, binding = 1) uniform texture2D ref_tex;
        layout(set = 0, binding = 2) uniform sampler processing_sampler;
        layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

        void main() {
            uvec2 target_coord = uvec2(0, 0);
            uvec2 ref_coord_1 = uvec2(12, 12);
            uvec2 ref_coord_2 = uvec2(0, 0);
            uvec2 block_size = uvec2(BLOCK_SIZE_X, BLOCK_SIZE_Y);
            vec4 result_1 = textureBlockMatchWindowSSDQCOM(
                sampler2D(target_tex, processing_sampler), target_coord,
                sampler2D(ref_tex, processing_sampler), ref_coord_1,
                block_size
            );
            vec4 result_2 = textureBlockMatchGatherSADQCOM(
                sampler2D(target_tex, processing_sampler), target_coord,
                sampler2D(ref_tex, processing_sampler), ref_coord_2,
                block_size
            );
        }
    )glsl";
    CreateComputePipelineHelper compute_pipe{ *this };
    constexpr std::array<VkSpecializationMapEntry, 2> map_entries{
        VkSpecializationMapEntry{ 0, 0, sizeof(uint32_t) },
        VkSpecializationMapEntry{ 1, sizeof(uint32_t), sizeof(uint32_t) },
    };
    std::array<uint32_t, 2> block_sizes{
        std::min(8u, image_processing_props.maxBlockMatchRegion.width),
        std::min(8u, image_processing_props.maxBlockMatchRegion.height),
    };
    VkSpecializationInfo specialization_info{};
    specialization_info.mapEntryCount = map_entries.size();
    specialization_info.pMapEntries = map_entries.data();
    specialization_info.dataSize = sizeof(block_sizes);
    specialization_info.pData = block_sizes.data();
    compute_pipe.cs_ = VkShaderObj{ *m_device, cs_source, VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_3,
                                    SPV_SOURCE_GLSL, &specialization_info };
    compute_pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM, 1, VK_SHADER_STAGE_ALL, nullptr},
                                  {1, VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM, 1, VK_SHADER_STAGE_ALL, nullptr},
                                  {2, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr}};
    compute_pipe.CreateComputePipeline();
    compute_pipe.descriptor_set_.WriteDescriptorImageInfo(0, target_image_view, nullptr, VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM);
    compute_pipe.descriptor_set_.WriteDescriptorImageInfo(1, reference_image_view, nullptr, VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM);
    compute_pipe.descriptor_set_.WriteDescriptorImageInfo(2, nullptr, sampler, VK_DESCRIPTOR_TYPE_SAMPLER);
    compute_pipe.descriptor_set_.UpdateDescriptorSets();

    m_command_buffer.Begin();
    vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute_pipe.pipeline_layout_, 0, 1,
                              &compute_pipe.descriptor_set_.set_, 0, nullptr);
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, compute_pipe);
    vk::CmdDispatch(m_command_buffer, 1, 1, 1);
    m_command_buffer.End();
}
