/*
 * 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.
 * Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
 *
 * 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 <cstdint>
#include "utils/cast_utils.h"
#include "../framework/layer_validation_tests.h"

#ifndef VK_USE_PLATFORM_WIN32_KHR
#include <sys/mman.h>
#endif

class NegativeMemory : public VkLayerTest {};

TEST_F(NegativeMemory, MemoryDecompressionEnabled) {
    TEST_DESCRIPTION("Validate memoryDecompression feature is enabled");
    AddRequiredExtensions(VK_EXT_MEMORY_DECOMPRESSION_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());
    VkPhysicalDeviceMemoryDecompressionPropertiesEXT mem_decomp_props_sao = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(mem_decomp_props_sao);
    if ((mem_decomp_props_sao.decompressionMethods & VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT) == 0) {
        GTEST_SKIP() << "GDeflate decompression method not supported";
    }

    VkDeviceSize buffer_size = 1024;
    VkDeviceSize decompressed_size = 2048;

    vkt::Buffer src_buffer(*m_device, buffer_size, 0, vkt::device_address);
    vkt::Buffer dst_buffer(*m_device, decompressed_size, 0, vkt::device_address);

    VkDecompressMemoryRegionEXT decompress_region = {};
    decompress_region.srcAddress = src_buffer.Address();
    decompress_region.dstAddress = dst_buffer.Address();
    decompress_region.compressedSize = buffer_size;
    decompress_region.decompressedSize = decompressed_size;

    VkDecompressMemoryInfoEXT decompress_info = vku::InitStructHelper();
    decompress_info.decompressionMethod = VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT;
    decompress_info.regionCount = 1;
    decompress_info.pRegions = &decompress_region;

    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-vkCmdDecompressMemoryEXT-memoryDecompression-11761");
    vk::CmdDecompressMemoryEXT(m_command_buffer, &decompress_info);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeMemory, MemoryDecompressionIndirectAddressUnaligned) {
    AddRequiredExtensions(VK_EXT_MEMORY_DECOMPRESSION_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::memoryDecompression);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());
    VkPhysicalDeviceMemoryDecompressionPropertiesEXT props = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(props);
    if ((props.decompressionMethods & VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT) == 0) {
        GTEST_SKIP() << "GDeflate decompression method not supported";
    }

    VkDeviceSize sz = 64;
    VkBufferUsageFlags2CreateInfo src_usage2 = vku::InitStructHelper();
    src_usage2.usage = VK_BUFFER_USAGE_2_MEMORY_DECOMPRESSION_BIT_EXT;
    vkt::Buffer src(*m_device, sz, src_usage2, vkt::device_address);
    VkBufferUsageFlags2CreateInfo dst_usage2 = vku::InitStructHelper();
    dst_usage2.usage = VK_BUFFER_USAGE_2_MEMORY_DECOMPRESSION_BIT_EXT;
    vkt::Buffer dst(*m_device, sz, dst_usage2, vkt::device_address);

    VkDecompressMemoryRegionEXT region{};
    region.srcAddress = src.Address();
    region.dstAddress = dst.Address();
    region.compressedSize = sz;
    region.decompressedSize = sz;

    VkDeviceSize ic_size = static_cast<VkDeviceSize>(sizeof(VkDecompressMemoryRegionEXT)) + 16;
    vkt::Buffer ic(*m_device, ic_size, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, vkt::device_address);
    void* p_ic = ic.Memory().Map();
    memcpy(p_ic, &region, sizeof(region));

    vkt::Buffer icc(*m_device, sizeof(uint32_t), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, vkt::device_address);
    uint32_t count = 1;
    void* p_cnt = icc.Memory().Map();
    memcpy(p_cnt, &count, sizeof(count));

    const VkMemoryDecompressionMethodFlagsEXT method = VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT;
    const uint32_t max_decompression_count = 1;
    const uint32_t stride = static_cast<uint32_t>(sizeof(VkDecompressMemoryRegionEXT));

    const VkDeviceAddress start = ic.Address() + 2;

    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-vkCmdDecompressMemoryIndirectCountEXT-indirectCommandsAddress-07695");
    vk::CmdDecompressMemoryIndirectCountEXT(m_command_buffer, method, start, icc.Address(), max_decompression_count, stride);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeMemory, MemoryDecompressionIndirectCountAddressUnaligned) {
    AddRequiredExtensions(VK_EXT_MEMORY_DECOMPRESSION_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::memoryDecompression);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());
    VkPhysicalDeviceMemoryDecompressionPropertiesEXT props = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(props);
    if ((props.decompressionMethods & VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT) == 0) {
        GTEST_SKIP() << "GDeflate decompression method not supported";
    }

    VkDeviceSize sz = 64;
    VkBufferUsageFlags2CreateInfo src_usage2 = vku::InitStructHelper();
    src_usage2.usage = VK_BUFFER_USAGE_2_MEMORY_DECOMPRESSION_BIT_EXT;
    vkt::Buffer src(*m_device, sz, src_usage2, vkt::device_address);
    VkBufferUsageFlags2CreateInfo dst_usage2 = vku::InitStructHelper();
    dst_usage2.usage = VK_BUFFER_USAGE_2_MEMORY_DECOMPRESSION_BIT_EXT;
    vkt::Buffer dst(*m_device, sz, dst_usage2, vkt::device_address);

    VkDecompressMemoryRegionEXT region{};
    region.srcAddress = src.Address();
    region.dstAddress = dst.Address();
    region.compressedSize = sz;
    region.decompressedSize = sz;

    vkt::Buffer ic(*m_device, sizeof(VkDecompressMemoryRegionEXT) + 16, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, vkt::device_address);
    void* p_ic = ic.Memory().Map();
    memcpy(p_ic, &region, sizeof(region));

    vkt::Buffer icc(*m_device, sizeof(uint32_t) + 8, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, vkt::device_address);
    uint32_t count = 1;
    void* p_cnt = icc.Memory().Map();
    memcpy(p_cnt, &count, sizeof(count));

    const VkMemoryDecompressionMethodFlagsEXT method = VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT;
    const uint32_t max_decompression_count = 1;
    const uint32_t stride = static_cast<uint32_t>(sizeof(VkDecompressMemoryRegionEXT));

    const VkDeviceAddress count_addr = icc.Address() + 2;

    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-vkCmdDecompressMemoryIndirectCountEXT-indirectCommandsCountAddress-07698");
    vk::CmdDecompressMemoryIndirectCountEXT(m_command_buffer, method, ic.Address(), count_addr, max_decompression_count, stride);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeMemory, MemoryDecompressionCompressedSizeZero) {
    AddRequiredExtensions(VK_EXT_MEMORY_DECOMPRESSION_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::memoryDecompression);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());
    VkPhysicalDeviceMemoryDecompressionPropertiesEXT props = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(props);
    if ((props.decompressionMethods & VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT) == 0) {
        GTEST_SKIP() << "GDeflate decompression method not supported";
    }

    VkDeviceSize size = 64;
    VkBufferUsageFlags2CreateInfo usage2 = vku::InitStructHelper();
    usage2.usage = VK_BUFFER_USAGE_2_MEMORY_DECOMPRESSION_BIT_EXT;
    vkt::Buffer src(*m_device, size, usage2, vkt::device_address);
    vkt::Buffer dst(*m_device, size, usage2, vkt::device_address);

    VkDecompressMemoryRegionEXT region{};
    region.srcAddress = src.Address();
    region.dstAddress = dst.Address();
    region.compressedSize = 0;
    region.decompressedSize = 64;

    VkDecompressMemoryInfoEXT info = vku::InitStructHelper();
    info.decompressionMethod = VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT;
    info.regionCount = 1;
    info.pRegions = &region;

    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-VkDecompressMemoryRegionEXT-compressedSize-11795");
    vk::CmdDecompressMemoryEXT(m_command_buffer, &info);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeMemory, MemoryDecompressionDecompressedSizeZero) {
    AddRequiredExtensions(VK_EXT_MEMORY_DECOMPRESSION_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::memoryDecompression);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());
    VkPhysicalDeviceMemoryDecompressionPropertiesEXT props = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(props);
    if ((props.decompressionMethods & VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT) == 0) {
        GTEST_SKIP() << "GDeflate decompression method not supported";
    }

    VkDeviceSize size = 64;
    VkBufferUsageFlags2CreateInfo usage2 = vku::InitStructHelper();
    usage2.usage = VK_BUFFER_USAGE_2_MEMORY_DECOMPRESSION_BIT_EXT;
    vkt::Buffer src(*m_device, size, usage2, vkt::device_address);
    vkt::Buffer dst(*m_device, size, usage2, vkt::device_address);

    VkDecompressMemoryRegionEXT region{};
    region.srcAddress = src.Address();
    region.dstAddress = dst.Address();
    region.compressedSize = 16;
    region.decompressedSize = 0;

    VkDecompressMemoryInfoEXT info = vku::InitStructHelper();
    info.decompressionMethod = VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT;
    info.regionCount = 1;
    info.pRegions = &region;

    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-VkDecompressMemoryRegionEXT-decompressedSize-11796");
    vk::CmdDecompressMemoryEXT(m_command_buffer, &info);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeMemory, MemoryDecompressionDstRangeExceedsBuffer) {
    AddRequiredExtensions(VK_EXT_MEMORY_DECOMPRESSION_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::memoryDecompression);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());
    VkPhysicalDeviceMemoryDecompressionPropertiesEXT props = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(props);
    if ((props.decompressionMethods & VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT) == 0) {
        GTEST_SKIP() << "GDeflate decompression method not supported";
    }

    const VkDeviceSize buf_size = 64;
    VkBufferUsageFlags2CreateInfo usage2 = vku::InitStructHelper();
    usage2.usage = VK_BUFFER_USAGE_2_MEMORY_DECOMPRESSION_BIT_EXT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT;
    vkt::Buffer buffer(*m_device, buf_size, usage2, vkt::device_address);
    const VkDeviceAddress base = buffer.Address();

    VkDecompressMemoryRegionEXT region{};
    region.srcAddress = base;
    region.compressedSize = 4;
    const VkDeviceAddress unaligned_dst = base + (buf_size - 4);
    region.dstAddress = unaligned_dst & ~static_cast<VkDeviceAddress>(3);
    region.decompressedSize = 8;

    VkDecompressMemoryInfoEXT info = vku::InitStructHelper();
    info.decompressionMethod = VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT;
    info.regionCount = 1;
    info.pRegions = &region;

    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-VkDecompressMemoryRegionEXT-dstAddress-07688");
    // Possible the src_buffer is allocated next to the dst_buffer in the driver
    m_errorMonitor->SetAllowedFailureMsg("VUID-VkDecompressMemoryRegionEXT-srcAddress-07691");
    vk::CmdDecompressMemoryEXT(m_command_buffer, &info);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeMemory, MemoryDecompressionIndirectStrideInvalid) {
    AddRequiredExtensions(VK_EXT_MEMORY_DECOMPRESSION_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::memoryDecompression);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());
    VkPhysicalDeviceMemoryDecompressionPropertiesEXT props = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(props);
    if ((props.decompressionMethods & VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT) == 0) {
        GTEST_SKIP() << "GDeflate decompression method not supported";
    }

    VkDeviceSize sz = 64;
    VkBufferUsageFlags2CreateInfo usage2 = vku::InitStructHelper();
    usage2.usage = VK_BUFFER_USAGE_2_MEMORY_DECOMPRESSION_BIT_EXT;
    vkt::Buffer src(*m_device, sz, usage2, vkt::device_address);
    vkt::Buffer dst(*m_device, sz, usage2, vkt::device_address);
    VkDecompressMemoryRegionEXT region{};
    region.srcAddress = src.Address();
    region.dstAddress = dst.Address();
    region.compressedSize = sz;
    region.decompressedSize = sz;

    vkt::Buffer ic(*m_device, sizeof(VkDecompressMemoryRegionEXT) + 16, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, vkt::device_address);
    void* p_ic = ic.Memory().Map();
    memcpy(p_ic, &region, sizeof(region));

    vkt::Buffer icc(*m_device, sizeof(uint32_t), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, vkt::device_address);
    uint32_t count = 1;
    void* p_cnt = icc.Memory().Map();
    memcpy(p_cnt, &count, sizeof(count));

    const VkMemoryDecompressionMethodFlagsEXT method = VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT;
    const uint32_t max_decompression_count = 1;
    const uint32_t bad_stride = 2;

    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-vkCmdDecompressMemoryIndirectCountEXT-stride-11767");
    vk::CmdDecompressMemoryIndirectCountEXT(m_command_buffer, method, ic.Address(), icc.Address(), max_decompression_count,
                                            bad_stride);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeMemory, MemoryDecompressionIndirectEnabled) {
    TEST_DESCRIPTION("Validate memoryDecompression feature is enabled");
    AddRequiredExtensions(VK_EXT_MEMORY_DECOMPRESSION_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::synchronization2);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());
    VkPhysicalDeviceMemoryDecompressionPropertiesEXT mem_decomp_props_ie = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(mem_decomp_props_ie);
    if ((mem_decomp_props_ie.decompressionMethods & VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT) == 0) {
        GTEST_SKIP() << "GDeflate decompression method not supported";
    }

    static const uint8_t kGdeflate_data[] = {0x47, 0x44, 0x46, 0x4c, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x40, 0x00,
                                             0x00, 0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
    const std::vector<uint8_t> compressed(std::begin(kGdeflate_data), std::end(kGdeflate_data));
    VkDeviceSize buffer_size = static_cast<VkDeviceSize>(compressed.size());
    VkDeviceSize decompressed_size = 64;

    VkBufferUsageFlags2CreateInfo src_usage2_ind = vku::InitStructHelper();
    src_usage2_ind.usage = VK_BUFFER_USAGE_2_MEMORY_DECOMPRESSION_BIT_EXT | VK_BUFFER_USAGE_2_INDIRECT_BUFFER_BIT;
    vkt::Buffer src_buffer(*m_device, buffer_size, src_usage2_ind, vkt::device_address);

    VkBufferUsageFlags2CreateInfo dst_usage2_ind = vku::InitStructHelper();
    dst_usage2_ind.usage = VK_BUFFER_USAGE_2_MEMORY_DECOMPRESSION_BIT_EXT;
    vkt::Buffer dst_buffer(*m_device, decompressed_size, dst_usage2_ind, vkt::device_address);

    void* p = src_buffer.Memory().Map();
    std::memcpy(p, compressed.data(), compressed.size());

    VkDecompressMemoryRegionEXT decompress_region = {};
    decompress_region.srcAddress = src_buffer.Address();
    decompress_region.dstAddress = dst_buffer.Address();
    decompress_region.compressedSize = buffer_size;
    decompress_region.decompressedSize = decompressed_size;
    VkDecompressMemoryRegionEXT cmds[2] = {decompress_region, decompress_region};

    vkt::Buffer ic_buffer(*m_device, sizeof(cmds), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, vkt::device_address);
    void* p_ic = ic_buffer.Memory().Map();
    memcpy(p_ic, cmds, sizeof(cmds));

    vkt::Buffer icc_buffer(*m_device, sizeof(uint32_t), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, vkt::device_address);
    uint32_t count = sizeof(cmds) / sizeof(VkDecompressMemoryRegionEXT);
    void* p_cnt = icc_buffer.Memory().Map();
    memcpy(p_cnt, &count, sizeof(count));

    VkPhysicalDeviceMemoryDecompressionPropertiesEXT memory_decompression_props = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(memory_decompression_props);

    VkMemoryDecompressionMethodFlagsEXT decompression_method = VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT;
    uint32_t max_decompression_count = count;
    uint32_t stride = (uint32_t)sizeof(VkDecompressMemoryRegionEXT);

    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-vkCmdDecompressMemoryIndirectCountEXT-None-07692");
    VkMemoryBarrier2 mem_barrier = vku::InitStructHelper();
    mem_barrier.srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT;
    mem_barrier.srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
    mem_barrier.dstAccessMask = VK_ACCESS_2_MEMORY_DECOMPRESSION_READ_BIT_EXT | VK_ACCESS_2_MEMORY_DECOMPRESSION_WRITE_BIT_EXT;
    mem_barrier.dstStageMask = VK_PIPELINE_STAGE_2_MEMORY_DECOMPRESSION_BIT_EXT;
    m_command_buffer.BarrierKHR(mem_barrier);

    vk::CmdDecompressMemoryIndirectCountEXT(m_command_buffer, decompression_method, ic_buffer.Address(), icc_buffer.Address(),
                                            max_decompression_count, stride);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeMemory, MemoryDecompressionIndirectCount) {
    AddRequiredExtensions(VK_EXT_MEMORY_DECOMPRESSION_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::memoryDecompression);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());
    VkPhysicalDeviceMemoryDecompressionPropertiesEXT mem_decomp_props_ic = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(mem_decomp_props_ic);
    if ((mem_decomp_props_ic.decompressionMethods & VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT) == 0) {
        GTEST_SKIP() << "GDeflate decompression method not supported";
    }

    VkDeviceSize buffer_size = 1024;
    VkDeviceSize decompressed_size = 2048;

    vkt::Buffer src_buffer(*m_device, buffer_size, 0, vkt::device_address);
    vkt::Buffer dst_buffer(*m_device, decompressed_size, 0, vkt::device_address);

    VkDecompressMemoryRegionEXT decompress_region = {};
    decompress_region.srcAddress = src_buffer.Address();
    decompress_region.dstAddress = dst_buffer.Address();
    decompress_region.compressedSize = buffer_size;
    decompress_region.decompressedSize = decompressed_size;
    VkDecompressMemoryRegionEXT cmds[2] = {decompress_region, decompress_region};

    VkBufferUsageFlags2CreateInfo ic_usage2 = vku::InitStructHelper();
    ic_usage2.usage = VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT;
    vkt::Buffer ic_buffer(*m_device, sizeof(cmds), ic_usage2, vkt::device_address);
    void* ic_buffer_address = ic_buffer.Memory().Map();
    memcpy(ic_buffer_address, &cmds, sizeof(cmds));

    VkBufferUsageFlags2CreateInfo icc_usage2 = vku::InitStructHelper();
    icc_usage2.usage = VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT;
    vkt::Buffer icc_buffer(*m_device, sizeof(uint32_t), icc_usage2, vkt::device_address);
    int cmdCount = sizeof(cmds) / sizeof(VkDecompressMemoryRegionEXT);
    void* icc_buffer_address = icc_buffer.Memory().Map();
    memcpy(icc_buffer_address, &cmdCount, sizeof(cmdCount));

    VkPhysicalDeviceMemoryDecompressionPropertiesEXT memory_decompression_props = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(memory_decompression_props);

    VkMemoryDecompressionMethodFlagsEXT decompression_method = VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT;
    uint32_t max_decompression_count = (uint32_t)memory_decompression_props.maxDecompressionIndirectCount;
    uint32_t stride = (uint32_t)sizeof(VkDecompressMemoryRegionEXT);

    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-vkCmdDecompressMemoryIndirectCountEXT-indirectCommandsAddress-07694");
    m_errorMonitor->SetDesiredError("VUID-vkCmdDecompressMemoryIndirectCountEXT-indirectCommandsCountAddress-07697");
    m_errorMonitor->SetDesiredError("VUID-vkCmdDecompressMemoryIndirectCountEXT-indirectCommandsAddress-11794");
    vk::CmdDecompressMemoryIndirectCountEXT(m_command_buffer, decompression_method, ic_buffer.Address(), icc_buffer.Address(),
                                            max_decompression_count, stride);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeMemory, MaxDecompressionCount) {
    AddRequiredExtensions(VK_EXT_MEMORY_DECOMPRESSION_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::memoryDecompression);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());
    VkPhysicalDeviceMemoryDecompressionPropertiesEXT mem_decomp_props_mdc = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(mem_decomp_props_mdc);
    if ((mem_decomp_props_mdc.decompressionMethods & VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT) == 0) {
        GTEST_SKIP() << "GDeflate decompression method not supported";
    }

    VkDeviceSize buffer_size = 1024;
    VkDeviceSize decompressed_size = 2048;

    vkt::Buffer src_buffer(*m_device, buffer_size, 0, vkt::device_address);

    vkt::Buffer dst_buffer(*m_device, decompressed_size, 0, vkt::device_address);

    VkDecompressMemoryRegionEXT decompress_region = {};
    decompress_region.srcAddress = src_buffer.Address();
    decompress_region.dstAddress = dst_buffer.Address();
    decompress_region.compressedSize = buffer_size;
    decompress_region.decompressedSize = decompressed_size;
    VkDecompressMemoryRegionEXT cmds[2] = {decompress_region, decompress_region};

    vkt::Buffer ic_buffer(*m_device, sizeof(cmds), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, vkt::device_address);
    void* p_ic = ic_buffer.Memory().Map();
    memcpy(p_ic, cmds, sizeof(cmds));

    vkt::Buffer icc_buffer(*m_device, sizeof(uint32_t), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, vkt::device_address);
    uint32_t count = sizeof(cmds) / sizeof(VkDecompressMemoryRegionEXT);
    void* p_cnt = icc_buffer.Memory().Map();
    memcpy(p_cnt, &count, sizeof(count));

    VkPhysicalDeviceMemoryDecompressionPropertiesEXT memory_decompression_props = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(memory_decompression_props);

    VkMemoryDecompressionMethodFlagsEXT decompression_method = VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT;
    uint32_t max_decompression_count = (uint32_t)memory_decompression_props.maxDecompressionIndirectCount;
    uint32_t stride = (uint32_t)sizeof(VkDecompressMemoryRegionEXT);

    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-vkCmdDecompressMemoryIndirectCountEXT-maxDecompressionCount-11768");
    vk::CmdDecompressMemoryIndirectCountEXT(m_command_buffer, decompression_method, ic_buffer.Address(), icc_buffer.Address(),
                                            max_decompression_count + 1, stride);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeMemory, MemoryDecompressionIndirectAddressRangeSameBuffer) {
    AddRequiredExtensions(VK_EXT_MEMORY_DECOMPRESSION_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::memoryDecompression);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());
    VkPhysicalDeviceMemoryDecompressionPropertiesEXT mem_decomp_props_arsb = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(mem_decomp_props_arsb);
    if ((mem_decomp_props_arsb.decompressionMethods & VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT) == 0) {
        GTEST_SKIP() << "GDeflate decompression method not supported";
    }

    VkDecompressMemoryRegionEXT region = {};
    region.srcAddress = 0;
    region.dstAddress = 0;
    region.compressedSize = 16;
    region.decompressedSize = 16;
    VkDecompressMemoryRegionEXT cmds[1] = {region};

    vkt::Buffer indirect_a(*m_device, sizeof(cmds), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, vkt::device_address);
    vkt::Buffer indirect_b(*m_device, 64, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, vkt::device_address);

    void* p_ic = indirect_a.Memory().Map();
    memcpy(p_ic, cmds, sizeof(cmds));

    vkt::Buffer count_buf(*m_device, sizeof(uint32_t), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, vkt::device_address);
    uint32_t count = 2;
    void* p_cnt = count_buf.Memory().Map();
    memcpy(p_cnt, &count, sizeof(count));

    const VkDeviceAddress end_minus_one = indirect_a.Address() + sizeof(cmds) - 1;
    const VkDeviceAddress start = end_minus_one & ~static_cast<VkDeviceAddress>(3);
    const uint32_t stride = (uint32_t)sizeof(VkDecompressMemoryRegionEXT);

    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-vkCmdDecompressMemoryIndirectCountEXT-indirectCommandsAddress-11794");
    vk::CmdDecompressMemoryIndirectCountEXT(m_command_buffer, VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT, start,
                                            count_buf.Address(), count, stride);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeMemory, MemoryDecompression) {
    AddRequiredExtensions(VK_EXT_MEMORY_DECOMPRESSION_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::memoryDecompression);
    RETURN_IF_SKIP(Init());
    VkPhysicalDeviceMemoryDecompressionPropertiesEXT mem_decomp_props_md = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(mem_decomp_props_md);
    if ((mem_decomp_props_md.decompressionMethods & VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT) == 0) {
        GTEST_SKIP() << "GDeflate decompression method not supported";
    }

    VkDecompressMemoryRegionEXT decompress_region = {};
    decompress_region.srcAddress = 1;
    decompress_region.dstAddress = 1;
    decompress_region.compressedSize = 1024;
    decompress_region.decompressedSize = 65537;

    VkDecompressMemoryInfoEXT decompress_info = vku::InitStructHelper();
    decompress_info.decompressionMethod = VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT;
    decompress_info.regionCount = 1;
    decompress_info.pRegions = &decompress_region;

    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-VkDecompressMemoryInfoEXT-decompressionMethod-11762");
    m_errorMonitor->SetDesiredError("VUID-VkDecompressMemoryRegionEXT-srcAddress-07685");
    m_errorMonitor->SetDesiredError("VUID-VkDecompressMemoryRegionEXT-dstAddress-07687");
    m_errorMonitor->SetDesiredError("VUID-VkDecompressMemoryRegionEXT-srcAddress-07691");
    vk::CmdDecompressMemoryEXT(m_command_buffer, &decompress_info);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeMemory, MemoryDecompressionBufferUsage) {
    AddRequiredExtensions(VK_EXT_MEMORY_DECOMPRESSION_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::memoryDecompression);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());
    VkPhysicalDeviceMemoryDecompressionPropertiesEXT mem_decomp_props_mdbu = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(mem_decomp_props_mdbu);
    if ((mem_decomp_props_mdbu.decompressionMethods & VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT) == 0) {
        GTEST_SKIP() << "GDeflate decompression method not supported";
    }

    VkDeviceSize buffer_size = 64;
    VkBufferUsageFlags2CreateInfo src_usage2 = vku::InitStructHelper();
    src_usage2.usage = 0;
    vkt::Buffer src_buffer(*m_device, buffer_size, src_usage2, vkt::device_address);

    VkBufferUsageFlags2CreateInfo dst_usage2 = vku::InitStructHelper();
    dst_usage2.usage = 0;
    vkt::Buffer dst_buffer(*m_device, buffer_size, dst_usage2, vkt::device_address);

    VkDecompressMemoryRegionEXT decompress_region = {};
    decompress_region.srcAddress = src_buffer.Address();
    decompress_region.dstAddress = dst_buffer.Address();
    decompress_region.compressedSize = buffer_size;
    decompress_region.decompressedSize = buffer_size;

    VkDecompressMemoryInfoEXT decompress_info = vku::InitStructHelper();
    decompress_info.decompressionMethod = VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT;
    decompress_info.regionCount = 1;
    decompress_info.pRegions = &decompress_region;

    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-VkDecompressMemoryRegionEXT-srcAddress-11764");
    m_errorMonitor->SetDesiredError("VUID-VkDecompressMemoryRegionEXT-dstAddress-11765");
    vk::CmdDecompressMemoryEXT(m_command_buffer, &decompress_info);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeMemory, MemoryDecompressionMethodSingleBit) {
    AddRequiredExtensions(VK_EXT_MEMORY_DECOMPRESSION_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::synchronization2);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::memoryDecompression);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());
    VkPhysicalDeviceMemoryDecompressionPropertiesEXT mem_decomp_props_mmsb = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(mem_decomp_props_mmsb);
    if ((mem_decomp_props_mmsb.decompressionMethods & VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT) == 0) {
        GTEST_SKIP() << "GDeflate decompression method not supported";
    }

    VkDeviceSize buffer_size = 64;
    VkDeviceSize decompressed_size = 64;

    VkBufferUsageFlags2CreateInfo src_usage2 = vku::InitStructHelper();
    src_usage2.usage = VK_BUFFER_USAGE_2_MEMORY_DECOMPRESSION_BIT_EXT;
    vkt::Buffer src_buffer(*m_device, buffer_size, src_usage2, vkt::device_address);

    VkBufferUsageFlags2CreateInfo dst_usage2 = vku::InitStructHelper();
    dst_usage2.usage = VK_BUFFER_USAGE_2_MEMORY_DECOMPRESSION_BIT_EXT;
    vkt::Buffer dst_buffer(*m_device, decompressed_size, dst_usage2, vkt::device_address);

    VkDecompressMemoryRegionEXT region = {};
    region.srcAddress = src_buffer.Address();
    region.dstAddress = dst_buffer.Address();
    region.compressedSize = buffer_size;
    region.decompressedSize = decompressed_size;

    VkMemoryDecompressionMethodFlagsEXT bad_method =
        VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT | (VkMemoryDecompressionMethodFlagsEXT)0x2;

    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-VkDecompressMemoryInfoEXT-decompressionMethod-07690");
    // Setting additional unsupported VkMemoryDecompressionMethodFlagBitsEXT bits to trigger error message
    m_errorMonitor->SetAllowedFailureMsg("VUID-VkDecompressMemoryInfoEXT-decompressionMethod-parameter");
    VkDecompressMemoryInfoEXT info = vku::InitStructHelper();
    info.decompressionMethod = bad_method;
    info.regionCount = 1;
    info.pRegions = &region;
    vk::CmdDecompressMemoryEXT(m_command_buffer, &info);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeMemory, MemoryDecompressionSrcAddressOutOfRange) {
    AddRequiredExtensions(VK_EXT_MEMORY_DECOMPRESSION_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::memoryDecompression);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    AddRequiredFeature(vkt::Feature::synchronization2);
    RETURN_IF_SKIP(Init());
    VkPhysicalDeviceMemoryDecompressionPropertiesEXT mem_decomp_props_sao = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(mem_decomp_props_sao);
    if ((mem_decomp_props_sao.decompressionMethods & VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT) == 0) {
        GTEST_SKIP() << "GDeflate decompression method not supported";
    }

    const VkDeviceSize buf_size = 128;
    VkBufferUsageFlags2CreateInfo src_usage2 = vku::InitStructHelper();
    src_usage2.usage = VK_BUFFER_USAGE_2_MEMORY_DECOMPRESSION_BIT_EXT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT;
    vkt::Buffer src_buffer(*m_device, buf_size, src_usage2, vkt::device_address);

    const VkDeviceAddress base = src_buffer.Address();

    const VkDeviceAddress src_near_end = base + buf_size - 8;
    const VkDeviceAddress src_addr = src_near_end & ~static_cast<VkDeviceAddress>(3);

    VkBufferUsageFlags2CreateInfo dst_usage2 = vku::InitStructHelper();
    dst_usage2.usage = VK_BUFFER_USAGE_2_MEMORY_DECOMPRESSION_BIT_EXT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT;
    vkt::Buffer dst_buffer(*m_device, buf_size, dst_usage2, vkt::device_address);
    const VkDeviceAddress dst_addr = dst_buffer.Address();

    VkDecompressMemoryRegionEXT region = {};
    region.srcAddress = src_addr;
    region.dstAddress = dst_addr;
    region.compressedSize = buf_size;
    region.decompressedSize = buf_size;

    VkDecompressMemoryInfoEXT info = vku::InitStructHelper();
    info.decompressionMethod = VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_EXT;
    info.regionCount = 1;
    info.pRegions = &region;

    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-VkDecompressMemoryRegionEXT-srcAddress-07686");
    // Possible the dst_buffer is allocated next to the src_buffer in the driver
    m_errorMonitor->SetAllowedFailureMsg("VUID-VkDecompressMemoryRegionEXT-srcAddress-07691");
    vk::CmdDecompressMemoryEXT(m_command_buffer, &info);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeMemory, MapMemory) {
    RETURN_IF_SKIP(Init());

    VkBufferCreateInfo buffer_ci = vku::InitStructHelper();
    buffer_ci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
    buffer_ci.size = 256;
    vkt::Buffer buffer(*m_device, buffer_ci, vkt::no_mem);

    VkMemoryRequirements mem_reqs;
    vk::GetBufferMemoryRequirements(device(), buffer, &mem_reqs);
    VkMemoryAllocateInfo alloc_info = vku::InitStructHelper();
    alloc_info.memoryTypeIndex = 0;

    // Ensure memory is big enough for both bindings
    // Want to make sure entire allocation is aligned to atom size
    const VkDeviceSize atom_size = m_device->Physical().limits_.nonCoherentAtomSize;
    static const VkDeviceSize allocation_size = atom_size * 64;
    alloc_info.allocationSize = allocation_size;
    bool pass = m_device->Physical().SetMemoryType(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
    if (!pass) {
        GTEST_SKIP() << "Failed to set memory type";
    }
    vkt::DeviceMemory mem(*m_device, alloc_info);

    uint8_t* pData;
    // Attempt to map memory size 0 is invalid
    m_errorMonitor->SetDesiredError("VUID-vkMapMemory-size-00680");
    vk::MapMemory(device(), mem, 0, 0, 0, (void**)&pData);
    m_errorMonitor->VerifyFound();
    // Map memory twice
    ASSERT_EQ(VK_SUCCESS, vk::MapMemory(device(), mem, 0, VK_WHOLE_SIZE, 0, (void**)&pData));
    m_errorMonitor->SetDesiredError("VUID-vkMapMemory-memory-00678");
    vk::MapMemory(device(), mem, 0, VK_WHOLE_SIZE, 0, (void**)&pData);
    m_errorMonitor->VerifyFound();

    // Unmap the memory to avoid re-map error
    vk::UnmapMemory(device(), mem);
    // overstep offset with VK_WHOLE_SIZE
    m_errorMonitor->SetDesiredError("VUID-vkMapMemory-offset-00679");
    vk::MapMemory(device(), mem, allocation_size + 1, VK_WHOLE_SIZE, 0, (void**)&pData);
    m_errorMonitor->VerifyFound();
    // overstep offset w/o VK_WHOLE_SIZE
    m_errorMonitor->SetDesiredError("VUID-vkMapMemory-offset-00679");
    vk::MapMemory(device(), mem, allocation_size + 1, VK_WHOLE_SIZE, 0, (void**)&pData);
    m_errorMonitor->VerifyFound();
    // overstep allocation w/o VK_WHOLE_SIZE
    m_errorMonitor->SetDesiredError("VUID-vkMapMemory-size-00681");
    vk::MapMemory(device(), mem, 1, allocation_size, 0, (void**)&pData);
    m_errorMonitor->VerifyFound();
    // Now error due to unmapping memory that's not mapped
    m_errorMonitor->SetDesiredError("VUID-vkUnmapMemory-memory-00689");
    vk::UnmapMemory(device(), mem);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, MapMemoryFlush) {
    RETURN_IF_SKIP(Init());

    VkBufferCreateInfo buffer_ci = vku::InitStructHelper();
    buffer_ci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
    buffer_ci.size = 256;
    vkt::Buffer buffer(*m_device, buffer_ci, vkt::no_mem);

    VkMemoryRequirements mem_reqs;
    vk::GetBufferMemoryRequirements(device(), buffer, &mem_reqs);
    VkMemoryAllocateInfo alloc_info = vku::InitStructHelper();
    alloc_info.memoryTypeIndex = 0;

    // Ensure memory is big enough for both bindings
    // Want to make sure entire allocation is aligned to atom
    const VkDeviceSize atom_size = m_device->Physical().limits_.nonCoherentAtomSize;
    static const VkDeviceSize allocation_size = atom_size * 64;
    alloc_info.allocationSize = allocation_size;
    bool pass = m_device->Physical().SetMemoryType(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
    if (!pass) {
        GTEST_SKIP() << "Failed to set memory type";
    }
    vkt::DeviceMemory mem(*m_device, alloc_info);

    uint8_t* pData;
    // Now map memory and cause errors due to flushing invalid ranges
    ASSERT_EQ(VK_SUCCESS, vk::MapMemory(device(), mem, 4 * atom_size, VK_WHOLE_SIZE, 0, (void**)&pData));
    VkMappedMemoryRange mem_range = vku::InitStructHelper();
    mem_range.memory = mem;
    mem_range.offset = atom_size;  // Error b/c offset less than offset of mapped mem
    m_errorMonitor->SetDesiredError("VUID-VkMappedMemoryRange-size-00685");
    vk::FlushMappedMemoryRanges(device(), 1, &mem_range);
    m_errorMonitor->VerifyFound();

    // Now flush range that oversteps mapped range
    vk::UnmapMemory(device(), mem);
    ASSERT_EQ(VK_SUCCESS, vk::MapMemory(device(), mem, 0, 4 * atom_size, 0, (void**)&pData));
    mem_range.offset = atom_size;
    mem_range.size = 4 * atom_size;  // Flushing bounds exceed mapped bounds
    m_errorMonitor->SetDesiredError("VUID-VkMappedMemoryRange-size-00685");
    vk::FlushMappedMemoryRanges(device(), 1, &mem_range);
    m_errorMonitor->VerifyFound();

    // Now flush range with VK_WHOLE_SIZE that oversteps offset
    vk::UnmapMemory(device(), mem);
    ASSERT_EQ(VK_SUCCESS, vk::MapMemory(device(), mem, 2 * atom_size, 4 * atom_size, 0, (void**)&pData));
    mem_range.offset = atom_size;
    mem_range.size = VK_WHOLE_SIZE;
    m_errorMonitor->SetDesiredError("VUID-VkMappedMemoryRange-size-00686");
    vk::FlushMappedMemoryRanges(device(), 1, &mem_range);
    m_errorMonitor->VerifyFound();

    // Try flushing and invalidating host memory not mapped
    vk::UnmapMemory(device(), mem);
    mem_range.offset = 0;
    mem_range.size = VK_WHOLE_SIZE;
    m_errorMonitor->SetDesiredError("VUID-VkMappedMemoryRange-memory-00684");
    vk::FlushMappedMemoryRanges(device(), 1, &mem_range);
    m_errorMonitor->VerifyFound();

    m_errorMonitor->SetDesiredError("VUID-VkMappedMemoryRange-memory-00684");
    vk::InvalidateMappedMemoryRanges(device(), 1, &mem_range);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, MapMemoryCoherentAtomSize) {
    RETURN_IF_SKIP(Init());
    if (IsPlatformMockICD()) {
        GTEST_SKIP() << "Test not supported by MockICD, MapMemory will fail ASAN";
    }

    const VkDeviceSize atom_size = m_device->Physical().limits_.nonCoherentAtomSize;
    if (atom_size < 4) {
        GTEST_SKIP() << "nonCoherentAtomSize is too small";
    }

    VkBufferCreateInfo buffer_ci = vku::InitStructHelper();
    buffer_ci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
    buffer_ci.size = 256;
    vkt::Buffer buffer(*m_device, buffer_ci, vkt::no_mem);

    VkMemoryRequirements mem_reqs;
    vk::GetBufferMemoryRequirements(device(), buffer, &mem_reqs);
    VkMemoryAllocateInfo alloc_info = vku::InitStructHelper();
    alloc_info.memoryTypeIndex = 0;

    // Ensure memory is big enough for both bindings
    // Want to make sure entire allocation is aligned to atom
    static const VkDeviceSize allocation_size = atom_size * 64;
    alloc_info.allocationSize = allocation_size;
    bool pass = m_device->Physical().SetMemoryType(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
    if (!pass) {
        GTEST_SKIP() << "Failed to set memory type";
    }
    vkt::DeviceMemory mem(*m_device, alloc_info);

    uint8_t* pData;

    // Now with an offset NOT a multiple of the device limit
    ASSERT_EQ(VK_SUCCESS, vk::MapMemory(device(), mem, 0, 4 * atom_size, 0, (void**)&pData));
    VkMappedMemoryRange mem_range = vku::InitStructHelper();
    mem_range.memory = mem;
    mem_range.offset = 3;  // Not a multiple of atom_size
    mem_range.size = VK_WHOLE_SIZE;
    m_errorMonitor->SetDesiredError("VUID-VkMappedMemoryRange-offset-00687");
    vk::FlushMappedMemoryRanges(device(), 1, &mem_range);
    m_errorMonitor->VerifyFound();

    // Now with a size NOT a multiple of the device limit
    vk::UnmapMemory(device(), mem);
    ASSERT_EQ(VK_SUCCESS, vk::MapMemory(device(), mem, 0, 4 * atom_size, 0, (void**)&pData));
    mem_range.offset = atom_size;
    mem_range.size = 2 * atom_size + 1;  // Not a multiple of atom_size
    m_errorMonitor->SetDesiredError("VUID-VkMappedMemoryRange-size-01390");
    vk::FlushMappedMemoryRanges(device(), 1, &mem_range);
    m_errorMonitor->VerifyFound();

    // Now with VK_WHOLE_SIZE and a mapping that does not end at a multiple of atom_size nor at the end of the memory.
    vk::UnmapMemory(device(), mem);
    ASSERT_EQ(VK_SUCCESS, vk::MapMemory(device(), mem, 0, 4 * atom_size + 1, 0, (void**)&pData));
    mem_range.offset = atom_size;
    mem_range.size = VK_WHOLE_SIZE;
    m_errorMonitor->SetDesiredError("VUID-VkMappedMemoryRange-size-01389");
    vk::FlushMappedMemoryRanges(device(), 1, &mem_range);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, MapMemory2) {
    TEST_DESCRIPTION("Attempt to map memory in a number of incorrect ways");

    AddRequiredExtensions(VK_KHR_MAP_MEMORY_2_EXTENSION_NAME);

    RETURN_IF_SKIP(Init());

    /* Vulkan doesn't have any requirements on what allocationSize can be
     * other than that it must be non-zero.  Pick 64KB because that should
     * work out to an even number of pages on basically any GPU.
     */
    const VkDeviceSize allocation_size = 64 << 10;

    VkMemoryAllocateInfo memory_info = vku::InitStructHelper();
    memory_info.allocationSize = allocation_size;

    bool pass = m_device->Physical().SetMemoryType(vvl::kU32Max, &memory_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
    ASSERT_TRUE(pass);

    vkt::DeviceMemory memory(*m_device, memory_info);

    VkMemoryMapInfo map_info = vku::InitStructHelper();
    map_info.memory = memory;

    VkMemoryUnmapInfo unmap_info = vku::InitStructHelper();
    unmap_info.memory = memory;

    uint8_t* pData;
    // Attempt to map memory size 0 is invalid
    map_info.offset = 0;
    map_info.size = 0;
    m_errorMonitor->SetDesiredError("VUID-VkMemoryMapInfo-size-07960");
    vk::MapMemory2KHR(device(), &map_info, (void**)&pData);
    m_errorMonitor->VerifyFound();
    // Map memory twice
    map_info.offset = 0;
    map_info.size = VK_WHOLE_SIZE;
    ASSERT_EQ(VK_SUCCESS, vk::MapMemory2KHR(device(), &map_info, (void**)&pData));
    m_errorMonitor->SetDesiredError("VUID-VkMemoryMapInfo-memory-07958");
    vk::MapMemory2KHR(device(), &map_info, (void**)&pData);
    m_errorMonitor->VerifyFound();

    // Unmap the memory to avoid re-map error
    vk::UnmapMemory2KHR(device(), &unmap_info);
    // overstep offset with VK_WHOLE_SIZE
    map_info.offset = allocation_size + 1;
    map_info.size = VK_WHOLE_SIZE;
    m_errorMonitor->SetDesiredError("VUID-VkMemoryMapInfo-offset-07959");
    vk::MapMemory2KHR(device(), &map_info, (void**)&pData);
    m_errorMonitor->VerifyFound();
    // overstep allocation w/o VK_WHOLE_SIZE
    map_info.offset = 1, map_info.size = allocation_size;
    m_errorMonitor->SetDesiredError("VUID-VkMemoryMapInfo-size-07961");
    vk::MapMemory2KHR(device(), &map_info, (void**)&pData);
    m_errorMonitor->VerifyFound();
    // Now error due to unmapping memory that's not mapped
    m_errorMonitor->SetDesiredError("VUID-VkMemoryUnmapInfo-memory-07964");
    vk::UnmapMemory2KHR(device(), &unmap_info);
    m_errorMonitor->VerifyFound();
}
TEST_F(NegativeMemory, MapMemoryNullppData) {
    TEST_DESCRIPTION("vkMapMemory but ppData is null");
    RETURN_IF_SKIP(Init());

    VkMemoryAllocateInfo memory_info = vku::InitStructHelper();
    memory_info.allocationSize = 1024;
    ASSERT_TRUE(m_device->Physical().SetMemoryType(vvl::kU32Max, &memory_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
    vkt::DeviceMemory memory(*m_device, memory_info);

    m_errorMonitor->SetDesiredError("VUID-vkMapMemory-ppData-parameter");
    vk::MapMemory(device(), memory, 0, VK_WHOLE_SIZE, 0, nullptr);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, MapMemWithoutHostVisibleBit) {
    TEST_DESCRIPTION("Allocate memory that is not mappable and then attempt to map it.");

    RETURN_IF_SKIP(Init());

    VkMemoryAllocateInfo mem_alloc = vku::InitStructHelper();
    mem_alloc.allocationSize = 1024;

    if (!m_device->Physical().SetMemoryType(0xFFFFFFFF, &mem_alloc, 0, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) {
        // If we can't find any unmappable memory this test doesn't make sense
        GTEST_SKIP() << "No unmappable memory types found";
    }

    vkt::DeviceMemory memory(*m_device, mem_alloc);
    void* mapped_address = nullptr;

    m_errorMonitor->SetDesiredError("VUID-vkMapMemory-memory-00682");
    m_errorMonitor->SetUnexpectedError("VUID-vkMapMemory-memory-00683");
    vk::MapMemory(device(), memory, 0, VK_WHOLE_SIZE, 0, &mapped_address);
    m_errorMonitor->VerifyFound();

    // Attempt to flush and invalidate non-host memory
    VkMappedMemoryRange memory_range = vku::InitStructHelper();
    memory_range.memory = memory;
    memory_range.offset = 0;
    memory_range.size = VK_WHOLE_SIZE;
    m_errorMonitor->SetDesiredError("VUID-VkMappedMemoryRange-memory-00684");
    vk::FlushMappedMemoryRanges(device(), 1, &memory_range);
    m_errorMonitor->VerifyFound();

    m_errorMonitor->SetDesiredError("VUID-VkMappedMemoryRange-memory-00684");
    vk::InvalidateMappedMemoryRanges(device(), 1, &memory_range);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, MapMemory2WithoutHostVisibleBit) {
    TEST_DESCRIPTION("Allocate memory that is not mappable and then attempt to map it.");
    AddRequiredExtensions(VK_KHR_MAP_MEMORY_2_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    VkMemoryAllocateInfo mem_alloc = vku::InitStructHelper();
    mem_alloc.allocationSize = 1024;
    if (!m_device->Physical().SetMemoryType(
            0xFFFFFFFF, &mem_alloc, 0,
            VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) {  // If we can't find any unmappable memory this test doesn't make sense
        GTEST_SKIP() << "No unmappable memory types found";
    }

    vkt::DeviceMemory memory(*m_device, mem_alloc);

    VkMemoryMapInfo map_info = vku::InitStructHelper();
    map_info.memory = memory;
    map_info.offset = 0;
    map_info.size = 32;
    uint8_t* pData;

    m_errorMonitor->SetDesiredError("VUID-VkMemoryMapInfo-memory-07962");
    vk::MapMemory2KHR(device(), &map_info, (void**)&pData);
    m_errorMonitor->VerifyFound();
}

#ifndef VK_USE_PLATFORM_WIN32_KHR
TEST_F(NegativeMemory, MapMemoryPlaced) {
    TEST_DESCRIPTION("Attempt to map placed memory in a number of incorrect ways");
    AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_MAP_MEMORY_2_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_MAP_MEMORY_PLACED_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::memoryMapPlaced);
    RETURN_IF_SKIP(Init());

    VkPhysicalDeviceMapMemoryPlacedPropertiesEXT map_placed_props = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(map_placed_props);

    // Vulkan doesn't have any requirements on what allocationSize can be
    // other than that it must be non-zero.  Pick 64KB because that should
    // work out to an even number of pages on basically any GPU.
    const VkDeviceSize allocation_size = map_placed_props.minPlacedMemoryMapAlignment * 16;

    VkMemoryAllocateInfo memory_info = vku::InitStructHelper();
    memory_info.allocationSize = allocation_size;

    bool pass = m_device->Physical().SetMemoryType(vvl::kU32Max, &memory_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
    ASSERT_TRUE(pass);

    vkt::DeviceMemory memory(*m_device, memory_info);

    VkMemoryMapInfo map_info = vku::InitStructHelper();
    map_info.memory = memory;
    map_info.flags = VK_MEMORY_MAP_PLACED_BIT_EXT;
    map_info.offset = 0;
    map_info.size = VK_WHOLE_SIZE;

    // No VkMemoryMapPlacedInfoEXT
    void* pData;
    m_errorMonitor->SetDesiredError("VUID-VkMemoryMapInfo-flags-09570");
    vk::MapMemory2KHR(device(), &map_info, &pData);
    m_errorMonitor->VerifyFound();

    VkMemoryMapPlacedInfoEXT placed_info = vku::InitStructHelper();
    map_info.pNext = &placed_info;

    // No VkMemoryMapPlacedInfoEXT::pPlacedAddress == NULL
    m_errorMonitor->SetDesiredError("VUID-VkMemoryMapInfo-flags-09570");
    vk::MapMemory2KHR(device(), &map_info, &pData);
    m_errorMonitor->VerifyFound();

    // Reserve two more pages in case we need to deal with any alignment weirdness.
    size_t reservation_size = allocation_size + map_placed_props.minPlacedMemoryMapAlignment;
    void* reservation = mmap(NULL, reservation_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    ASSERT_TRUE(reservation != MAP_FAILED);

    // Align up to minPlacedMemoryMapAlignment
    uintptr_t align_1 = map_placed_props.minPlacedMemoryMapAlignment - 1;
    void* addr = reinterpret_cast<void*>((reinterpret_cast<uintptr_t>(reservation) + align_1) & ~align_1);

    placed_info.pPlacedAddress = ((char*)addr) + (map_placed_props.minPlacedMemoryMapAlignment / 2);

    // Unaligned VkMemoryMapPlacedInfoEXT::pPlacedAddress
    m_errorMonitor->SetDesiredError("VUID-VkMemoryMapPlacedInfoEXT-pPlacedAddress-09577");
    vk::MapMemory2KHR(device(), &map_info, &pData);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, MemoryMapRangePlacedEnabled) {
    TEST_DESCRIPTION("Test when memoryMapRangePlaced is enabled");
    AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_MAP_MEMORY_2_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_MAP_MEMORY_PLACED_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::memoryMapPlaced);
    AddRequiredFeature(vkt::Feature::memoryMapRangePlaced);
    RETURN_IF_SKIP(Init());

    VkPhysicalDeviceMapMemoryPlacedPropertiesEXT map_placed_props = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(map_placed_props);
    const VkDeviceSize allocation_size = map_placed_props.minPlacedMemoryMapAlignment * 16;

    VkMemoryAllocateInfo memory_info = vku::InitStructHelper();
    memory_info.allocationSize = allocation_size;

    bool pass = m_device->Physical().SetMemoryType(vvl::kU32Max, &memory_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
    ASSERT_TRUE(pass);
    vkt::DeviceMemory memory(*m_device, memory_info);

    // Reserve two more pages in case we need to deal with any alignment weirdness.
    size_t reservation_size = allocation_size + map_placed_props.minPlacedMemoryMapAlignment;
    void* reservation = mmap(NULL, reservation_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    ASSERT_TRUE(reservation != MAP_FAILED);

    uintptr_t align_1 = map_placed_props.minPlacedMemoryMapAlignment - 1;
    void* addr = reinterpret_cast<void*>((reinterpret_cast<uintptr_t>(reservation) + align_1) & ~align_1);

    VkMemoryMapPlacedInfoEXT placed_info = vku::InitStructHelper();
    placed_info.pPlacedAddress = addr;
    VkMemoryMapInfo map_info = vku::InitStructHelper(&placed_info);
    map_info.memory = memory;
    map_info.flags = VK_MEMORY_MAP_PLACED_BIT_EXT;
    map_info.size = VK_WHOLE_SIZE;
    map_info.offset = map_placed_props.minPlacedMemoryMapAlignment / 2;

    void* pData;
    // Unaligned offset
    m_errorMonitor->SetDesiredError("VUID-VkMemoryMapInfo-flags-09573");
    vk::MapMemory2KHR(device(), &map_info, &pData);
    m_errorMonitor->VerifyFound();

    map_info.offset = 0;
    map_info.size = allocation_size - (map_placed_props.minPlacedMemoryMapAlignment / 2);

    // Unaligned size
    m_errorMonitor->SetDesiredError("VUID-VkMemoryMapInfo-flags-09574");
    vk::MapMemory2KHR(device(), &map_info, &pData);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, MemoryMapRangePlacedDisabled) {
    TEST_DESCRIPTION("Test when memoryMapRangePlaced is disabled");
    AddRequiredExtensions(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_MAP_MEMORY_2_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_MAP_MEMORY_PLACED_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::memoryMapPlaced);

    RETURN_IF_SKIP(Init());

    VkPhysicalDeviceMapMemoryPlacedPropertiesEXT map_placed_props = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(map_placed_props);
    const VkDeviceSize allocation_size = map_placed_props.minPlacedMemoryMapAlignment * 16;

    VkMemoryAllocateInfo memory_info = vku::InitStructHelper();
    memory_info.allocationSize = allocation_size;

    bool pass = m_device->Physical().SetMemoryType(vvl::kU32Max, &memory_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
    ASSERT_TRUE(pass);
    vkt::DeviceMemory memory(*m_device, memory_info);

    // Reserve two more pages in case we need to deal with any alignment weirdness.
    size_t reservation_size = allocation_size + map_placed_props.minPlacedMemoryMapAlignment;
    void* reservation = mmap(NULL, reservation_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    ASSERT_TRUE(reservation != MAP_FAILED);

    uintptr_t align_1 = map_placed_props.minPlacedMemoryMapAlignment - 1;
    void* addr = reinterpret_cast<void*>((reinterpret_cast<uintptr_t>(reservation) + align_1) & ~align_1);

    VkMemoryMapPlacedInfoEXT placed_info = vku::InitStructHelper();
    placed_info.pPlacedAddress = addr;
    VkMemoryMapInfo map_info = vku::InitStructHelper(&placed_info);
    map_info.memory = memory;
    map_info.flags = VK_MEMORY_MAP_PLACED_BIT_EXT;
    map_info.size = VK_WHOLE_SIZE;
    map_info.offset = map_placed_props.minPlacedMemoryMapAlignment;

    void* pData;
    // Non-zero offset
    m_errorMonitor->SetDesiredError("VUID-VkMemoryMapInfo-flags-09571");
    vk::MapMemory2KHR(device(), &map_info, &pData);
    m_errorMonitor->VerifyFound();

    map_info.offset = 0;
    map_info.size = allocation_size - map_placed_props.minPlacedMemoryMapAlignment;

    // Not VK_WHOLE_SIZE
    m_errorMonitor->SetDesiredError("VUID-VkMemoryMapInfo-flags-09572");
    vk::MapMemory2KHR(device(), &map_info, &pData);
    m_errorMonitor->VerifyFound();

    const VkDeviceSize unaligned_size = allocation_size + map_placed_props.minPlacedMemoryMapAlignment / 2;
    memory_info.allocationSize = unaligned_size;
    vkt::DeviceMemory unaligned_memory(*m_device, memory_info);

    map_info.memory = unaligned_memory;
    map_info.offset = 0;
    map_info.size = VK_WHOLE_SIZE;

    m_errorMonitor->SetDesiredError("VUID-VkMemoryMapInfo-flags-09651");
    vk::MapMemory2KHR(device(), &map_info, &pData);
    m_errorMonitor->VerifyFound();

    map_info.size = unaligned_size;

    m_errorMonitor->SetDesiredError("VUID-VkMemoryMapInfo-flags-09574");
    vk::MapMemory2KHR(device(), &map_info, &pData);
    m_errorMonitor->VerifyFound();
}
#endif

TEST_F(NegativeMemory, RebindMemoryMultiObject) {
    RETURN_IF_SKIP(Init());

    // Create an image, allocate memory, free it, and then try to bind it
    VkImageCreateInfo image_create_info =
        vkt::Image::ImageCreateInfo2D(32, 32, 1, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT);
    vkt::Image image(*m_device, image_create_info, vkt::no_mem);
    VkMemoryRequirements mem_reqs = image.MemoryRequirements();

    VkMemoryAllocateInfo mem_alloc = vku::InitStructHelper();
    // Introduce failure, do NOT set memProps to
    // VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
    mem_alloc.memoryTypeIndex = 1;
    mem_alloc.allocationSize = mem_reqs.size;
    ASSERT_TRUE(m_device->Physical().SetMemoryType(mem_reqs.memoryTypeBits, &mem_alloc, 0));

    vkt::DeviceMemory mem1(*m_device, mem_alloc);
    vkt::DeviceMemory mem2(*m_device, mem_alloc);

    // Bind first memory object to Image object
    vk::BindImageMemory(device(), image, mem1, 0);

    // Introduce validation failure, try to bind a different memory object to
    // the same image object
    m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-image-07460");
    vk::BindImageMemory(device(), image, mem2, 0);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, QueryMemoryCommitmentWithoutLazyProperty) {
    TEST_DESCRIPTION("Attempt to query memory commitment on memory without lazy allocation");
    RETURN_IF_SKIP(Init());

    auto image_ci = vkt::Image::ImageCreateInfo2D(32, 32, 1, 1, VK_FORMAT_B8G8R8A8_UNORM,
                                                  VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
    vkt::Image image(*m_device, image_ci, vkt::no_mem);

    const auto mem_reqs = image.MemoryRequirements();
    VkMemoryAllocateInfo image_alloc_info = vku::InitStructHelper();
    image_alloc_info.allocationSize = mem_reqs.size;

    // the last argument is the "forbid" argument for SetMemoryType, disallowing
    // that particular memory type rather than requiring it
    if (!m_device->Physical().SetMemoryType(mem_reqs.memoryTypeBits, &image_alloc_info, 0,
                                            VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)) {
        GTEST_SKIP() << "Failed to set memory type";
    }
    vkt::DeviceMemory mem(*m_device, image_alloc_info);

    m_errorMonitor->SetDesiredError("VUID-vkGetDeviceMemoryCommitment-memory-00690");
    VkDeviceSize size;
    vk::GetDeviceMemoryCommitment(device(), mem, &size);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, BindImageMemoryType) {
    TEST_DESCRIPTION("Create an image, allocate memory, set a bad typeIndex and then try to bind it");
    RETURN_IF_SKIP(Init());

    VkImageCreateInfo image_create_info =
        vkt::Image::ImageCreateInfo2D(32, 32, 1, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT);
    vkt::Image image(*m_device, image_create_info, vkt::no_mem);

    VkMemoryAllocateInfo mem_alloc = vku::InitStructHelper();
    mem_alloc.allocationSize = 0;
    mem_alloc.memoryTypeIndex = 0;

    VkMemoryRequirements mem_reqs;
    vk::GetImageMemoryRequirements(device(), image, &mem_reqs);
    mem_alloc.allocationSize = mem_reqs.size;

    // Introduce Failure, select invalid TypeIndex
    VkPhysicalDeviceMemoryProperties memory_info;

    vk::GetPhysicalDeviceMemoryProperties(Gpu(), &memory_info);
    uint32_t i = 0;
    for (; i < memory_info.memoryTypeCount; i++) {
        // Would require deviceCoherentMemory feature
        if (memory_info.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD) {
            continue;
        }
        // would require protected feature
        if (memory_info.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_PROTECTED_BIT) {
            continue;
        }
        if ((mem_reqs.memoryTypeBits & (1 << i)) == 0) {
            mem_alloc.memoryTypeIndex = i;
            break;
        }
    }
    if (i >= memory_info.memoryTypeCount) {
        GTEST_SKIP() << "No invalid memory type index could be found";
    }

    m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-memory-01047");
    vkt::DeviceMemory mem(*m_device, mem_alloc);
    vk::BindImageMemory(device(), image, mem, 0);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, BindMemory) {
    AddRequiredFeature(vkt::Feature::sparseBinding);
    RETURN_IF_SKIP(Init());

    VkImageCreateInfo image_create_info =
        vkt::Image::ImageCreateInfo2D(256, 256, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT);
    auto buffer_create_info = vkt::Buffer::CreateInfo(4 * 1024 * 1024, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);

    // Create an image/buffer, allocate memory, free it, and then try to bind it
    {
        vkt::Image image(*m_device, image_create_info, vkt::no_mem);
        vkt::Buffer buffer(*m_device, buffer_create_info, vkt::no_mem);

        VkMemoryRequirements image_mem_reqs = {}, buffer_mem_reqs = {};
        vk::GetImageMemoryRequirements(device(), image, &image_mem_reqs);
        vk::GetBufferMemoryRequirements(device(), buffer, &buffer_mem_reqs);

        VkMemoryAllocateInfo image_mem_alloc = vku::InitStructHelper();
        VkMemoryAllocateInfo buffer_mem_alloc = vku::InitStructHelper();
        image_mem_alloc.allocationSize = image_mem_reqs.size;
        m_device->Physical().SetMemoryType(image_mem_reqs.memoryTypeBits, &image_mem_alloc, 0);
        buffer_mem_alloc.allocationSize = buffer_mem_reqs.size;
        m_device->Physical().SetMemoryType(buffer_mem_reqs.memoryTypeBits, &buffer_mem_alloc, 0);

        VkDeviceMemory image_mem = VK_NULL_HANDLE, buffer_mem = VK_NULL_HANDLE;
        vk::AllocateMemory(device(), &image_mem_alloc, nullptr, &image_mem);
        vk::AllocateMemory(device(), &buffer_mem_alloc, nullptr, &buffer_mem);

        vk::FreeMemory(device(), image_mem, nullptr);
        vk::FreeMemory(device(), buffer_mem, nullptr);

        m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-memory-parameter");
        vk::BindImageMemory(device(), image, image_mem, 0);
        m_errorMonitor->VerifyFound();

        m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-memory-parameter");
        vk::BindBufferMemory(device(), buffer, buffer_mem, 0);
        m_errorMonitor->VerifyFound();
    }

    // Try to bind memory to an object that already has a memory binding
    {
        vkt::Image image(*m_device, image_create_info, vkt::no_mem);
        vkt::Buffer buffer(*m_device, buffer_create_info, vkt::no_mem);

        VkMemoryRequirements image_mem_reqs = {}, buffer_mem_reqs = {};
        vk::GetImageMemoryRequirements(device(), image, &image_mem_reqs);
        vk::GetBufferMemoryRequirements(device(), buffer, &buffer_mem_reqs);
        VkMemoryAllocateInfo image_alloc_info = vku::InitStructHelper();
        VkMemoryAllocateInfo buffer_alloc_info = vku::InitStructHelper();
        image_alloc_info.allocationSize = image_mem_reqs.size;
        buffer_alloc_info.allocationSize = buffer_mem_reqs.size;
        m_device->Physical().SetMemoryType(image_mem_reqs.memoryTypeBits, &image_alloc_info, 0);
        m_device->Physical().SetMemoryType(buffer_mem_reqs.memoryTypeBits, &buffer_alloc_info, 0);

        vkt::DeviceMemory image_mem(*m_device, image_alloc_info);
        vkt::DeviceMemory buffer_mem(*m_device, buffer_alloc_info);

        vk::BindImageMemory(device(), image, image_mem, 0);
        m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-image-07460");
        vk::BindImageMemory(device(), image, image_mem, 0);
        m_errorMonitor->VerifyFound();

        vk::BindBufferMemory(device(), buffer, buffer_mem, 0);
        m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-buffer-07459");
        vk::BindBufferMemory(device(), buffer, buffer_mem, 0);
        m_errorMonitor->VerifyFound();
    }

    // Try to bind memory to an object with an invalid memoryOffset
    {
        vkt::Image image(*m_device, image_create_info, vkt::no_mem);
        vkt::Buffer buffer(*m_device, buffer_create_info, vkt::no_mem);

        VkMemoryRequirements image_mem_reqs = {}, buffer_mem_reqs = {};
        vk::GetImageMemoryRequirements(device(), image, &image_mem_reqs);
        vk::GetBufferMemoryRequirements(device(), buffer, &buffer_mem_reqs);
        VkMemoryAllocateInfo image_alloc_info = vku::InitStructHelper();
        VkMemoryAllocateInfo buffer_alloc_info = vku::InitStructHelper();
        // Leave some extra space for alignment wiggle room
        image_alloc_info.allocationSize = image_mem_reqs.size + image_mem_reqs.alignment;
        buffer_alloc_info.allocationSize = buffer_mem_reqs.size + buffer_mem_reqs.alignment;
        m_device->Physical().SetMemoryType(image_mem_reqs.memoryTypeBits, &image_alloc_info, 0);
        m_device->Physical().SetMemoryType(buffer_mem_reqs.memoryTypeBits, &buffer_alloc_info, 0);
        vkt::DeviceMemory image_mem(*m_device, image_alloc_info);
        vkt::DeviceMemory buffer_mem(*m_device, buffer_alloc_info);

        // Test unaligned memory offset
        {
            if (image_mem_reqs.alignment > 1) {
                VkDeviceSize image_offset = 1;
                m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-None-10735");
                vk::BindImageMemory(device(), image, image_mem, image_offset);
                m_errorMonitor->VerifyFound();
            }

            if (buffer_mem_reqs.alignment > 1) {
                VkDeviceSize buffer_offset = 1;
                m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-None-10739");
                vk::BindBufferMemory(device(), buffer, buffer_mem, buffer_offset);
                m_errorMonitor->VerifyFound();
            }
        }

        // Test memory offsets outside the memory allocation
        {
            VkDeviceSize image_offset =
                (image_alloc_info.allocationSize + image_mem_reqs.alignment) & ~(image_mem_reqs.alignment - 1);
            m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-memoryOffset-01046");
            vk::BindImageMemory(device(), image, image_mem, image_offset);
            m_errorMonitor->VerifyFound();

            VkDeviceSize buffer_offset =
                (buffer_alloc_info.allocationSize + buffer_mem_reqs.alignment) & ~(buffer_mem_reqs.alignment - 1);
            m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-memoryOffset-01031");
            vk::BindBufferMemory(device(), buffer, buffer_mem, buffer_offset);
            m_errorMonitor->VerifyFound();
        }

        // Test memory offsets within the memory allocation, but which leave too little memory for
        // the resource.
        {
            VkDeviceSize image_offset = (image_mem_reqs.size - 1) & ~(image_mem_reqs.alignment - 1);
            if ((image_offset > 0) && (image_mem_reqs.size < (image_alloc_info.allocationSize - image_mem_reqs.alignment))) {
                m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-None-10737");
                vk::BindImageMemory(device(), image, image_mem, image_offset);
                m_errorMonitor->VerifyFound();
            }

            VkDeviceSize buffer_offset = (buffer_mem_reqs.size - 1) & ~(buffer_mem_reqs.alignment - 1);
            if (buffer_offset > 0) {
                m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-None-10741");
                vk::BindBufferMemory(device(), buffer, buffer_mem, buffer_offset);
                m_errorMonitor->VerifyFound();
            }
        }
    }

    // Try to bind memory to an image created with sparse memory flags
    {
        VkImageCreateInfo sparse_image_create_info = image_create_info;
        sparse_image_create_info.flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
        VkImageFormatProperties image_format_properties = {};
        VkResult err = GetImageFormatProps(Gpu(), sparse_image_create_info, image_format_properties);
        if (!m_device->Physical().Features().sparseResidencyImage2D || err == VK_ERROR_FORMAT_NOT_SUPPORTED) {
            // most likely means sparse formats aren't supported here; skip this test.
        } else {
            if (image_format_properties.maxExtent.width == 0) {
                GTEST_SKIP() << "Sparse image format not supported";
            } else {
                vkt::Image sparse_image(*m_device, sparse_image_create_info, vkt::no_mem);
                VkMemoryRequirements sparse_mem_reqs = {};
                vk::GetImageMemoryRequirements(device(), sparse_image, &sparse_mem_reqs);
                if (sparse_mem_reqs.memoryTypeBits != 0) {
                    VkMemoryAllocateInfo sparse_mem_alloc = vku::InitStructHelper();
                    sparse_mem_alloc.allocationSize = sparse_mem_reqs.size;
                    sparse_mem_alloc.memoryTypeIndex = 0;
                    m_device->Physical().SetMemoryType(sparse_mem_reqs.memoryTypeBits, &sparse_mem_alloc, 0);
                    vkt::DeviceMemory memory(*m_device, sparse_mem_alloc);
                    m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-image-01045");
                    vk::BindImageMemory(device(), sparse_image, memory, 0);
                    m_errorMonitor->VerifyFound();
                }
            }
        }
    }

    // Try to bind memory to a buffer created with sparse memory flags
    {
        VkBufferCreateInfo sparse_buffer_create_info = buffer_create_info;
        sparse_buffer_create_info.flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
        if (!m_device->Physical().Features().sparseResidencyBuffer) {
            // most likely means sparse formats aren't supported here; skip this test.
        } else {
            vkt::Buffer sparse_buffer(*m_device, sparse_buffer_create_info, vkt::no_mem);
            VkMemoryRequirements sparse_mem_reqs = {};
            vk::GetBufferMemoryRequirements(device(), sparse_buffer, &sparse_mem_reqs);
            if (sparse_mem_reqs.memoryTypeBits != 0) {
                VkMemoryAllocateInfo sparse_mem_alloc = vku::InitStructHelper();
                sparse_mem_alloc.allocationSize = sparse_mem_reqs.size;
                sparse_mem_alloc.memoryTypeIndex = 0;
                m_device->Physical().SetMemoryType(sparse_mem_reqs.memoryTypeBits, &sparse_mem_alloc, 0);
                vkt::DeviceMemory memory(*m_device, sparse_mem_alloc);
                m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-buffer-01030");
                vk::BindBufferMemory(device(), sparse_buffer, memory, 0);
                m_errorMonitor->VerifyFound();
            }
        }
    }
}

TEST_F(NegativeMemory, BindMemoryUnsupported) {
    RETURN_IF_SKIP(Init());

    VkImageCreateInfo image_create_info =
        vkt::Image::ImageCreateInfo2D(256, 256, 1, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT);
    vkt::Image image(*m_device, image_create_info, vkt::no_mem);

    auto buffer_info = vkt::Buffer::CreateInfo(4 * 1024 * 1024, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
    vkt::Buffer buffer(*m_device, buffer_info, vkt::no_mem);

    VkMemoryRequirements image_mem_reqs = {}, buffer_mem_reqs = {};
    vk::GetImageMemoryRequirements(device(), image, &image_mem_reqs);
    vk::GetBufferMemoryRequirements(device(), buffer, &buffer_mem_reqs);
    VkMemoryAllocateInfo image_alloc_info = vku::InitStructHelper();
    VkMemoryAllocateInfo buffer_alloc_info = vku::InitStructHelper();
    image_alloc_info.allocationSize = image_mem_reqs.size;
    buffer_alloc_info.allocationSize = buffer_mem_reqs.size;
    // Create a mask of available memory types *not* supported by these resources,
    // and try to use one of them.
    VkPhysicalDeviceMemoryProperties memory_properties = {};
    vk::GetPhysicalDeviceMemoryProperties(m_device->Physical(), &memory_properties);

    uint32_t image_unsupported_mem_type_bits = ((1 << memory_properties.memoryTypeCount) - 1) & ~image_mem_reqs.memoryTypeBits;
    // can't have protected bit because feature bit is not added
    bool found_type =
        m_device->Physical().SetMemoryType(image_unsupported_mem_type_bits, &image_alloc_info, 0,
                                           VK_MEMORY_PROPERTY_PROTECTED_BIT | VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD);
    if (image_unsupported_mem_type_bits != 0 && found_type) {
        vkt::DeviceMemory memory(*m_device, image_alloc_info);
        m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-memory-01047");
        vk::BindImageMemory(device(), image, memory, 0);
        m_errorMonitor->VerifyFound();
    }

    uint32_t buffer_unsupported_mem_type_bits = ((1 << memory_properties.memoryTypeCount) - 1) & ~buffer_mem_reqs.memoryTypeBits;
    found_type = m_device->Physical().SetMemoryType(buffer_unsupported_mem_type_bits, &buffer_alloc_info, 0,
                                                    VK_MEMORY_PROPERTY_PROTECTED_BIT | VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD);
    if (buffer_unsupported_mem_type_bits != 0 && found_type) {
        vkt::DeviceMemory memory(*m_device, buffer_alloc_info);
        m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-memory-01035");
        vk::BindBufferMemory(device(), buffer, memory, 0);
        m_errorMonitor->VerifyFound();
    }
}

TEST_F(NegativeMemory, BindMemoryNoCheckBuffer) {
    TEST_DESCRIPTION("Tests case were no call to memory requirements was made prior to binding");
    RETURN_IF_SKIP(Init());

    VkBufferCreateInfo buffer_create_info = vku::InitStructHelper();
    buffer_create_info.size = 1024;
    buffer_create_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;

    // Create 2 buffers, one that is checked and one that isn't by GetBufferMemoryRequirements
    vkt::Buffer buffer(*m_device, buffer_create_info, vkt::no_mem);
    vkt::Buffer unchecked_buffer(*m_device, buffer_create_info, vkt::no_mem);

    VkMemoryRequirements buffer_mem_reqs = {};
    vk::GetBufferMemoryRequirements(device(), buffer, &buffer_mem_reqs);
    VkMemoryAllocateInfo buffer_alloc_info = vku::InitStructHelper();
    // Leave some extra space for alignment wiggle room
    buffer_alloc_info.allocationSize = buffer_mem_reqs.size + buffer_mem_reqs.alignment;
    ASSERT_TRUE(m_device->Physical().SetMemoryType(buffer_mem_reqs.memoryTypeBits, &buffer_alloc_info, 0));
    vkt::DeviceMemory buffer_mem(*m_device, buffer_alloc_info);
    vkt::DeviceMemory unchecked_buffer_mem(*m_device, buffer_alloc_info);

    if (buffer_mem_reqs.alignment > 1) {
        VkDeviceSize buffer_offset = 1;

        m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-None-10739");
        vk::BindBufferMemory(device(), buffer, buffer_mem, buffer_offset);
        m_errorMonitor->VerifyFound();

        // Should trigger same VUID even when image was never checked
        // this makes an assumption that the driver will return the same image requirements for same createImageInfo where even
        // being close to running out of heap space
        m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-None-10739");
        vk::BindBufferMemory(device(), unchecked_buffer, unchecked_buffer_mem, buffer_offset);
        m_errorMonitor->VerifyFound();
    }
}

TEST_F(NegativeMemory, BindMemoryNoCheckImage) {
    TEST_DESCRIPTION("Tests case were no call to memory requirements was made prior to binding");
    RETURN_IF_SKIP(Init());

    VkImageCreateInfo image_create_info =
        vkt::Image::ImageCreateInfo2D(256, 256, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT);

    // Create 2 images, one that is checked and one that isn't by GetImageMemoryRequirements
    vkt::Image image(*m_device, image_create_info, vkt::no_mem);
    vkt::Image unchecked_image(*m_device, image_create_info, vkt::no_mem);

    VkMemoryRequirements image_mem_reqs = {};
    vk::GetImageMemoryRequirements(device(), image, &image_mem_reqs);
    VkMemoryAllocateInfo image_alloc_info = vku::InitStructHelper();
    // Leave some extra space for alignment wiggle room
    image_alloc_info.allocationSize = image_mem_reqs.size + image_mem_reqs.alignment;
    ASSERT_TRUE(m_device->Physical().SetMemoryType(image_mem_reqs.memoryTypeBits, &image_alloc_info, 0));
    vkt::DeviceMemory image_mem(*m_device, image_alloc_info);
    vkt::DeviceMemory unchecked_image_mem(*m_device, image_alloc_info);

    // single-plane image
    if (image_mem_reqs.alignment > 1) {
        VkDeviceSize image_offset = 1;

        m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-None-10735");
        vk::BindImageMemory(device(), image, image_mem, image_offset);
        m_errorMonitor->VerifyFound();

        // Should trigger same VUID even when image was never checked
        // this makes an assumption that the driver will return the same image requirements for same createImageInfo where even
        // being close to running out of heap space
        m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-None-10735");
        vk::BindImageMemory(device(), unchecked_image, unchecked_image_mem, image_offset);
        m_errorMonitor->VerifyFound();
    }
}

TEST_F(NegativeMemory, BindMemoryNoCheckMultiPlane) {
    TEST_DESCRIPTION("Tests case were no call to memory requirements was made prior to binding");
    AddRequiredExtensions(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    // Check for support of format used by all multi-planar tests
    const VkFormat mp_format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
    VkFormatProperties mp_format_properties;
    vk::GetPhysicalDeviceFormatProperties(m_device->Physical(), mp_format, &mp_format_properties);
    if (!((mp_format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_DISJOINT_BIT) &&
          (mp_format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))) {
        GTEST_SKIP() << "test rely on a supported disjoint format";
    }

    VkImageCreateInfo mp_image_create_info = vkt::Image::ImageCreateInfo2D(256, 256, 1, 1, mp_format, VK_IMAGE_USAGE_SAMPLED_BIT);
    mp_image_create_info.flags = VK_IMAGE_CREATE_DISJOINT_BIT;

    // Array represent planes for disjoint images
    VkDeviceMemory mp_image_mem[2] = {VK_NULL_HANDLE, VK_NULL_HANDLE};
    VkDeviceMemory mp_unchecked_image_mem[2] = {VK_NULL_HANDLE, VK_NULL_HANDLE};
    VkMemoryRequirements2 mp_image_mem_reqs2[2];
    VkMemoryAllocateInfo mp_image_alloc_info[2];

    vkt::Image mp_image(*m_device, mp_image_create_info, vkt::no_mem);
    vkt::Image mp_unchecked_image(*m_device, mp_image_create_info, vkt::no_mem);

    VkImagePlaneMemoryRequirementsInfo image_plane_req = vku::InitStructHelper();
    image_plane_req.planeAspect = VK_IMAGE_ASPECT_PLANE_0_BIT;

    VkImageMemoryRequirementsInfo2 mem_req_info2 = vku::InitStructHelper(&image_plane_req);
    mem_req_info2.image = mp_image;
    mp_image_mem_reqs2[0] = vku::InitStructHelper();
    vk::GetImageMemoryRequirements2KHR(device(), &mem_req_info2, &mp_image_mem_reqs2[0]);

    image_plane_req.planeAspect = VK_IMAGE_ASPECT_PLANE_1_BIT;
    mp_image_mem_reqs2[1] = vku::InitStructHelper();
    vk::GetImageMemoryRequirements2KHR(device(), &mem_req_info2, &mp_image_mem_reqs2[1]);

    mp_image_alloc_info[0] = vku::InitStructHelper();
    mp_image_alloc_info[1] = vku::InitStructHelper();

    mp_image_alloc_info[0].allocationSize = mp_image_mem_reqs2[0].memoryRequirements.size;
    ASSERT_TRUE(
        m_device->Physical().SetMemoryType(mp_image_mem_reqs2[0].memoryRequirements.memoryTypeBits, &mp_image_alloc_info[0], 0));
    // Leave some extra space for alignment wiggle room
    mp_image_alloc_info[1].allocationSize =
        mp_image_mem_reqs2[1].memoryRequirements.size + mp_image_mem_reqs2[1].memoryRequirements.alignment;
    ASSERT_TRUE(
        m_device->Physical().SetMemoryType(mp_image_mem_reqs2[1].memoryRequirements.memoryTypeBits, &mp_image_alloc_info[1], 0));

    ASSERT_EQ(VK_SUCCESS, vk::AllocateMemory(device(), &mp_image_alloc_info[0], NULL, &mp_image_mem[0]));
    ASSERT_EQ(VK_SUCCESS, vk::AllocateMemory(device(), &mp_image_alloc_info[1], NULL, &mp_image_mem[1]));
    ASSERT_EQ(VK_SUCCESS, vk::AllocateMemory(device(), &mp_image_alloc_info[0], NULL, &mp_unchecked_image_mem[0]));
    ASSERT_EQ(VK_SUCCESS, vk::AllocateMemory(device(), &mp_image_alloc_info[1], NULL, &mp_unchecked_image_mem[1]));

    // Sets an invalid offset to plane 1
    if (mp_image_mem_reqs2[1].memoryRequirements.alignment > 1) {
        VkBindImagePlaneMemoryInfo plane_memory_info[2];
        plane_memory_info[0] = vku::InitStructHelper();
        plane_memory_info[0].planeAspect = VK_IMAGE_ASPECT_PLANE_0_BIT;
        plane_memory_info[1] = vku::InitStructHelper();
        plane_memory_info[1].planeAspect = VK_IMAGE_ASPECT_PLANE_1_BIT;

        VkBindImageMemoryInfo bind_image_info[2];
        bind_image_info[0] = vku::InitStructHelper(&plane_memory_info[0]);
        bind_image_info[0].image = mp_image;
        bind_image_info[0].memory = mp_image_mem[0];
        bind_image_info[0].memoryOffset = 0;
        bind_image_info[1] = vku::InitStructHelper(&plane_memory_info[1]);
        bind_image_info[1].image = mp_image;
        bind_image_info[1].memory = mp_image_mem[1];
        bind_image_info[1].memoryOffset = 1;  // off alignment

        m_errorMonitor->SetDesiredError("VUID-VkBindImageMemoryInfo-pNext-01620");
        vk::BindImageMemory2KHR(device(), 2, bind_image_info);
        m_errorMonitor->VerifyFound();

        // Should trigger same VUID even when image was never checked
        // this makes an assumption that the driver will return the same image requirements for same createImageInfo where even
        // being close to running out of heap space
        bind_image_info[0].image = mp_unchecked_image;
        bind_image_info[0].memory = mp_unchecked_image_mem[0];
        bind_image_info[1].image = mp_unchecked_image;
        bind_image_info[1].memory = mp_unchecked_image_mem[1];
        m_errorMonitor->SetDesiredError("VUID-VkBindImageMemoryInfo-pNext-01620");
        vk::BindImageMemory2KHR(device(), 2, bind_image_info);
        m_errorMonitor->VerifyFound();
    }

    vk::FreeMemory(device(), mp_image_mem[0], NULL);
    vk::FreeMemory(device(), mp_image_mem[1], NULL);
    vk::FreeMemory(device(), mp_unchecked_image_mem[0], NULL);
    vk::FreeMemory(device(), mp_unchecked_image_mem[1], NULL);
}

TEST_F(NegativeMemory, BindMemory2BindInfos) {
    TEST_DESCRIPTION("These tests deal with VK_KHR_bind_memory_2 and invalid VkBindImageMemoryInfo* pBindInfos");
    AddRequiredExtensions(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    VkImageCreateInfo image_create_info =
        vkt::Image::ImageCreateInfo2D(256, 256, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT);

    // Create 2 image with 2 memory objects
    vkt::Image image_a(*m_device, image_create_info, vkt::no_mem);
    vkt::Image image_b(*m_device, image_create_info, vkt::no_mem);

    VkMemoryRequirements image_mem_reqs = {};
    vk::GetImageMemoryRequirements(device(), image_a, &image_mem_reqs);
    VkMemoryAllocateInfo image_alloc_info = vku::InitStructHelper();
    image_alloc_info.allocationSize = image_mem_reqs.size;
    ASSERT_TRUE(m_device->Physical().SetMemoryType(image_mem_reqs.memoryTypeBits, &image_alloc_info, 0));
    vkt::DeviceMemory image_a_mem(*m_device, image_alloc_info);

    vk::GetImageMemoryRequirements(device(), image_b, &image_mem_reqs);
    image_alloc_info.allocationSize = image_mem_reqs.size;
    ASSERT_TRUE(m_device->Physical().SetMemoryType(image_mem_reqs.memoryTypeBits, &image_alloc_info, 0));
    vkt::DeviceMemory image_b_mem(*m_device, image_alloc_info);

    // Try binding same image twice in array
    VkBindImageMemoryInfo bind_image_info[3];
    bind_image_info[0] = vku::InitStructHelper();
    bind_image_info[0].image = image_a;
    bind_image_info[0].memory = image_a_mem;
    bind_image_info[0].memoryOffset = 0;
    bind_image_info[1] = vku::InitStructHelper();
    bind_image_info[1].image = image_b;
    bind_image_info[1].memory = image_b_mem;
    bind_image_info[1].memoryOffset = 0;
    bind_image_info[2] = bind_image_info[0];  // duplicate bind

    m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory2-pBindInfos-04006");
    vk::BindImageMemory2KHR(device(), 3, bind_image_info);
    m_errorMonitor->VerifyFound();

    // Bind same image to 2 different memory in same array
    bind_image_info[1].image = image_a;
    m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory2-pBindInfos-04006");
    vk::BindImageMemory2KHR(device(), 2, bind_image_info);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, BindMemory2BindInfosMultiPlane) {
    TEST_DESCRIPTION("These tests deal with VK_KHR_bind_memory_2 and invalid VkBindImageMemoryInfo* pBindInfos");
    AddRequiredExtensions(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    VkImageCreateInfo image_create_info =
        vkt::Image::ImageCreateInfo2D(256, 256, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT);

    const VkFormat mp_format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;

    // Check for support of format used by all multi-planar tests
    VkFormatProperties mp_format_properties;
    vk::GetPhysicalDeviceFormatProperties(m_device->Physical(), mp_format, &mp_format_properties);
    if (!((mp_format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_DISJOINT_BIT) &&
          (mp_format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))) {
        GTEST_SKIP() << "test rely on a supported disjoint format";
    }

    // Creat 1 normal, not disjoint image
    vkt::Image normal_image(*m_device, image_create_info, vkt::no_mem);
    VkMemoryRequirements image_mem_reqs = {};
    vk::GetImageMemoryRequirements(device(), normal_image, &image_mem_reqs);
    VkMemoryAllocateInfo image_alloc_info = vku::InitStructHelper();
    image_alloc_info.allocationSize = image_mem_reqs.size;
    ASSERT_TRUE(m_device->Physical().SetMemoryType(image_mem_reqs.memoryTypeBits, &image_alloc_info, 0));
    vkt::DeviceMemory normal_image_mem(*m_device, image_alloc_info);

    // Create 2 disjoint images with memory backing each plane
    VkImageCreateInfo mp_image_create_info = image_create_info;
    mp_image_create_info.format = mp_format;
    mp_image_create_info.flags = VK_IMAGE_CREATE_DISJOINT_BIT;

    VkDeviceMemory mp_image_a_mem[2] = {VK_NULL_HANDLE, VK_NULL_HANDLE};
    VkDeviceMemory mp_image_b_mem[2] = {VK_NULL_HANDLE, VK_NULL_HANDLE};
    vkt::Image mp_image_a(*m_device, mp_image_create_info, vkt::no_mem);
    vkt::Image mp_image_b(*m_device, mp_image_create_info, vkt::no_mem);

    auto allocate = [this](VkImage mp_image, VkDeviceMemory* mp_image_mem, VkImageAspectFlagBits plane) {
        VkImagePlaneMemoryRequirementsInfo image_plane_req = vku::InitStructHelper();
        image_plane_req.planeAspect = plane;

        VkImageMemoryRequirementsInfo2 mem_req_info2 = vku::InitStructHelper(&image_plane_req);
        mem_req_info2.image = mp_image;

        VkMemoryRequirements2 mp_image_mem_reqs2 = vku::InitStructHelper();

        vk::GetImageMemoryRequirements2KHR(device(), &mem_req_info2, &mp_image_mem_reqs2);

        VkMemoryAllocateInfo mp_image_alloc_info = vku::InitStructHelper();
        mp_image_alloc_info.allocationSize = mp_image_mem_reqs2.memoryRequirements.size;
        ASSERT_TRUE(
            m_device->Physical().SetMemoryType(mp_image_mem_reqs2.memoryRequirements.memoryTypeBits, &mp_image_alloc_info, 0));
        vk::AllocateMemory(device(), &mp_image_alloc_info, NULL, mp_image_mem);
    };

    allocate(mp_image_a, &mp_image_a_mem[0], VK_IMAGE_ASPECT_PLANE_0_BIT);
    allocate(mp_image_a, &mp_image_a_mem[1], VK_IMAGE_ASPECT_PLANE_1_BIT);
    allocate(mp_image_b, &mp_image_b_mem[0], VK_IMAGE_ASPECT_PLANE_0_BIT);
    allocate(mp_image_b, &mp_image_b_mem[1], VK_IMAGE_ASPECT_PLANE_1_BIT);

    VkBindImagePlaneMemoryInfo plane_memory_info[2];
    plane_memory_info[0] = vku::InitStructHelper();
    plane_memory_info[0].planeAspect = VK_IMAGE_ASPECT_PLANE_0_BIT;
    plane_memory_info[1] = vku::InitStructHelper();
    plane_memory_info[1].planeAspect = VK_IMAGE_ASPECT_PLANE_1_BIT;

    // set all sType and memoryOffset as they are the same
    VkBindImageMemoryInfo bind_image_info[6];
    for (int i = 0; i < 6; i++) {
        bind_image_info[i] = vku::InitStructHelper();
        bind_image_info[i].memoryOffset = 0;
    }

    // Try only binding part of image_b
    bind_image_info[0].pNext = (void*)&plane_memory_info[0];
    bind_image_info[0].image = mp_image_a;
    bind_image_info[0].memory = mp_image_a_mem[0];
    bind_image_info[1].pNext = (void*)&plane_memory_info[1];
    bind_image_info[1].image = mp_image_a;
    bind_image_info[1].memory = mp_image_a_mem[1];
    bind_image_info[2].pNext = (void*)&plane_memory_info[0];
    bind_image_info[2].image = mp_image_b;
    bind_image_info[2].memory = mp_image_b_mem[0];
    m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory2-pBindInfos-02858");
    vk::BindImageMemory2KHR(device(), 3, bind_image_info);
    m_errorMonitor->VerifyFound();

    // Same thing, but mix in a non-disjoint image
    bind_image_info[3].pNext = nullptr;
    bind_image_info[3].image = normal_image;
    bind_image_info[3].memory = normal_image_mem;
    m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory2-pBindInfos-02858");
    vk::BindImageMemory2KHR(device(), 4, bind_image_info);
    m_errorMonitor->VerifyFound();

    // Try binding image_b plane 1 twice
    // Valid case where binding disjoint and non-disjoint
    bind_image_info[4].pNext = (void*)&plane_memory_info[1];
    bind_image_info[4].image = mp_image_b;
    bind_image_info[4].memory = mp_image_b_mem[1];
    bind_image_info[5].pNext = (void*)&plane_memory_info[1];
    bind_image_info[5].image = mp_image_b;
    bind_image_info[5].memory = mp_image_b_mem[1];
    m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory2-pBindInfos-04006");
    vk::BindImageMemory2KHR(device(), 6, bind_image_info);
    m_errorMonitor->VerifyFound();

    // Try binding image_a with no plane specified
    bind_image_info[0].pNext = nullptr;
    m_errorMonitor->SetDesiredError("VUID-VkBindImageMemoryInfo-image-07736");
    vk::BindImageMemory2KHR(device(), 1, bind_image_info);
    m_errorMonitor->VerifyFound();
    bind_image_info[0].pNext = (void*)&plane_memory_info[0];

    // Valid case of binding 2 disjoint image and normal image by removing duplicate
    vk::BindImageMemory2KHR(device(), 5, bind_image_info);

    vk::FreeMemory(device(), mp_image_a_mem[0], nullptr);
    vk::FreeMemory(device(), mp_image_a_mem[1], nullptr);
    vk::FreeMemory(device(), mp_image_b_mem[0], nullptr);
    vk::FreeMemory(device(), mp_image_b_mem[1], nullptr);
}

TEST_F(NegativeMemory, BindMemoryToDestroyedObject) {
    RETURN_IF_SKIP(Init());

    // Create an image object, allocate memory, destroy the object and then try
    // to bind it
    VkImage image;
    VkMemoryRequirements mem_reqs;

    VkImageCreateInfo image_create_info =
        vkt::Image::ImageCreateInfo2D(32, 32, 1, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT);
    vk::CreateImage(device(), &image_create_info, nullptr, &image);

    VkMemoryAllocateInfo mem_alloc = vku::InitStructHelper();
    mem_alloc.allocationSize = 0;
    mem_alloc.memoryTypeIndex = 0;
    vk::GetImageMemoryRequirements(device(), image, &mem_reqs);

    mem_alloc.allocationSize = mem_reqs.size;
    bool pass = m_device->Physical().SetMemoryType(mem_reqs.memoryTypeBits, &mem_alloc, 0);
    ASSERT_TRUE(pass);

    vkt::DeviceMemory mem(*m_device, mem_alloc);

    // Introduce validation failure, destroy Image object before binding
    vk::DestroyImage(device(), image, nullptr);

    // Now Try to bind memory to this destroyed object
    m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-image-parameter");
    vk::BindImageMemory(device(), image, mem, 0);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, AllocationCount) {
    RETURN_IF_SKIP(Init());

    const uint32_t max_mems = m_device->Physical().limits_.maxMemoryAllocationCount;
    if (max_mems > 4096) {
        GTEST_SKIP() << "maxMemoryAllocationCount is too high";
    }

    std::vector<VkDeviceMemory> mems;
    mems.reserve(max_mems + 1);

    m_errorMonitor->SetDesiredError("VUID-vkAllocateMemory-maxMemoryAllocationCount-04101");

    VkMemoryAllocateInfo mem_alloc = vku::InitStructHelper();
    mem_alloc.memoryTypeIndex = 0;
    mem_alloc.allocationSize = 4;

    VkResult err = VK_SUCCESS;
    uint32_t i;
    for (i = 0; i <= max_mems; i++) {
        err = vk::AllocateMemory(device(), &mem_alloc, NULL, &mems[i]);
        if (err != VK_SUCCESS) {
            break;
        }
    }
    m_errorMonitor->VerifyFound();

    for (uint32_t j = 0; j < i; j++) {
        vk::FreeMemory(device(), mems[j], NULL);
    }
}

TEST_F(NegativeMemory, ImageMemoryNotBound) {
    TEST_DESCRIPTION("Attempt to draw with an image which has not had memory bound to it.");
    RETURN_IF_SKIP(Init());

    const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
    VkImageCreateInfo image_create_info = vkt::Image::ImageCreateInfo2D(
        32, 32, 1, 1, tex_format, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
    vkt::Image image(*m_device, image_create_info, vkt::no_mem);
    // Have to bind memory to image before recording cmd in cmd buffer using it
    VkMemoryRequirements mem_reqs;
    bool pass;
    VkMemoryAllocateInfo mem_alloc = vku::InitStructHelper();
    mem_alloc.memoryTypeIndex = 0;
    vk::GetImageMemoryRequirements(device(), image, &mem_reqs);
    mem_alloc.allocationSize = mem_reqs.size;
    pass = m_device->Physical().SetMemoryType(mem_reqs.memoryTypeBits, &mem_alloc, 0);
    ASSERT_TRUE(pass);
    vkt::DeviceMemory image_mem(*m_device, mem_alloc);

    // Introduce error, do not call vk::BindImageMemory(device(), image, image_mem, 0);
    m_errorMonitor->SetDesiredError("VUID-vkCmdClearColorImage-image-00003");

    m_command_buffer.Begin();
    VkClearColorValue ccv;
    ccv.float32[0] = 1.0f;
    ccv.float32[1] = 1.0f;
    ccv.float32[2] = 1.0f;
    ccv.float32[3] = 1.0f;
    VkImageSubresourceRange isr = {};
    isr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
    isr.baseArrayLayer = 0;
    isr.baseMipLevel = 0;
    isr.layerCount = 1;
    isr.levelCount = 1;
    vk::CmdClearColorImage(m_command_buffer, image, VK_IMAGE_LAYOUT_GENERAL, &ccv, 1, &isr);
    m_command_buffer.End();

    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, BufferMemoryNotBound) {
    TEST_DESCRIPTION("Attempt to copy from a buffer which has not had memory bound to it.");
    RETURN_IF_SKIP(Init());

    vkt::Image image(*m_device, 128, 128, VK_FORMAT_B8G8R8A8_UNORM,
                     VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);

    VkBufferCreateInfo buf_info = vku::InitStructHelper();
    buf_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
    buf_info.size = 1024;
    vkt::Buffer buffer(*m_device, buf_info, vkt::no_mem);

    VkMemoryAllocateInfo alloc_info = vku::InitStructHelper();
    alloc_info.allocationSize = 1024;
    VkMemoryRequirements mem_reqs;
    vk::GetBufferMemoryRequirements(device(), buffer, &mem_reqs);
    if (!m_device->Physical().SetMemoryType(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) {
        GTEST_SKIP() << "Failed to set memory type";
    }

    VkBufferImageCopy region = {};
    region.bufferRowLength = 16;
    region.bufferImageHeight = 16;
    region.imageSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
    region.imageExtent = {4, 4, 1};
    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-vkCmdCopyBufferToImage-srcBuffer-00176");
    vk::CmdCopyBufferToImage(m_command_buffer, buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeMemory, DedicatedAllocationBinding) {
    AddRequiredExtensions(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());
    VkMemoryPropertyFlags mem_flags = 0;
    const VkDeviceSize resource_size = 1024;
    auto buffer_info = vkt::Buffer::CreateInfo(resource_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
    vkt::Buffer buffer(*m_device, buffer_info, vkt::no_mem);
    auto buffer_alloc_info = vkt::DeviceMemory::GetResourceAllocInfo(*m_device, buffer.MemoryRequirements(), mem_flags);
    VkMemoryDedicatedAllocateInfo buffer_dedicated_info = vku::InitStructHelper();
    buffer_dedicated_info.buffer = buffer;
    buffer_alloc_info.pNext = &buffer_dedicated_info;
    vkt::DeviceMemory dedicated_buffer_memory(*m_device, buffer_alloc_info);

    vkt::Buffer wrong_buffer(*m_device, buffer_info, vkt::no_mem);

    // Bind with wrong buffer
    m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-memory-01508");
    vk::BindBufferMemory(*m_device, wrong_buffer, dedicated_buffer_memory, 0);
    m_errorMonitor->VerifyFound();

    // Bind with non-zero offset (same VUID)
    m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-memory-01508");  // offset must be zero
    m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-None-10741");    // offset pushes us past size
    auto offset = buffer.MemoryRequirements().alignment;
    vk::BindBufferMemory(*m_device, buffer, dedicated_buffer_memory, offset);
    m_errorMonitor->VerifyFound();

    // Bind correctly (depends on the "skip" above)
    vk::BindBufferMemory(*m_device, buffer, dedicated_buffer_memory, 0);

    // And for images...
    auto image_info =
        vkt::Image::ImageCreateInfo2D(resource_size, 1, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT);
    vkt::Image image(*m_device, image_info, vkt::no_mem);
    vkt::Image wrong_image(*m_device, image_info, vkt::no_mem);

    VkMemoryDedicatedAllocateInfo image_dedicated_info = vku::InitStructHelper();
    image_dedicated_info.image = image;
    auto image_alloc_info = vkt::DeviceMemory::GetResourceAllocInfo(*m_device, image.MemoryRequirements(), mem_flags);
    image_alloc_info.pNext = &image_dedicated_info;
    vkt::DeviceMemory dedicated_image_memory(*m_device, image_alloc_info);

    // Bind with wrong image
    m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-memory-02628");
    vk::BindImageMemory(*m_device, wrong_image, dedicated_image_memory, 0);
    m_errorMonitor->VerifyFound();

    // Bind with non-zero offset (same VUID)
    m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-memory-02628");  // offset must be zero
    m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-None-10737");    // offset pushes us past size
    auto image_offset = image.MemoryRequirements().alignment;
    vk::BindImageMemory(*m_device, image, dedicated_image_memory, image_offset);
    m_errorMonitor->VerifyFound();

    // Bind correctly (depends on the "skip" above)
    vk::BindImageMemory(*m_device, image, dedicated_image_memory, 0);
}

TEST_F(NegativeMemory, DedicatedAllocationImageAliasing) {
    AddRequiredExtensions(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
    AddRequiredExtensions(VK_NV_DEDICATED_ALLOCATION_IMAGE_ALIASING_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::dedicatedAllocationImageAliasing);
    RETURN_IF_SKIP(Init());

    VkMemoryPropertyFlags mem_flags = 0;
    const VkDeviceSize resource_size = 1024;

    auto image_info =
        vkt::Image::ImageCreateInfo2D(resource_size, 1, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT);
    vkt::Image image(*m_device, image_info, vkt::no_mem);
    vkt::Image identical_image(*m_device, image_info, vkt::no_mem);
    vkt::Image post_delete_image(*m_device, image_info, vkt::no_mem);

    VkMemoryDedicatedAllocateInfo image_dedicated_info = vku::InitStructHelper();
    image_dedicated_info.image = image;
    auto image_alloc_info = vkt::DeviceMemory::GetResourceAllocInfo(*m_device, image.MemoryRequirements(), mem_flags);
    image_alloc_info.pNext = &image_dedicated_info;
    vkt::DeviceMemory dedicated_image_memory(*m_device, image_alloc_info);

    // Bind with different but identical image
    vk::BindImageMemory(*m_device, identical_image, dedicated_image_memory, 0);

    image_info =
        vkt::Image::ImageCreateInfo2D(resource_size - 1, 1, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT);
    vkt::Image smaller_image(*m_device, image_info, vkt::no_mem);

    // Bind with a smaller image
    vk::BindImageMemory(*m_device, smaller_image, dedicated_image_memory, 0);

    image_info =
        vkt::Image::ImageCreateInfo2D(resource_size + 1, 1, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT);
    vkt::Image larger_image(*m_device, image_info, vkt::no_mem);

    // Bind with a larger image (not supported, and not enough memory)
    m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-memory-02629");
    if (larger_image.MemoryRequirements().size > image.MemoryRequirements().size) {
        m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-None-10737");
    }
    vk::BindImageMemory(*m_device, larger_image, dedicated_image_memory, 0);
    m_errorMonitor->VerifyFound();

    // Bind with non-zero offset
    m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-memory-02629");  // offset must be zero
    m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-None-10737");    // offset pushes us past size
    auto image_offset = image.MemoryRequirements().alignment;
    vk::BindImageMemory(*m_device, image, dedicated_image_memory, image_offset);
    m_errorMonitor->VerifyFound();

    // Bind correctly (depends on the "skip" above)
    vk::BindImageMemory(*m_device, image, dedicated_image_memory, 0);

    image.Destroy();  // destroy the original image
    vk::BindImageMemory(*m_device, post_delete_image, dedicated_image_memory, 0);
}

TEST_F(NegativeMemory, BufferDeviceAddressEXT) {
    TEST_DESCRIPTION("Test VK_EXT_buffer_device_address.");
    AddRequiredExtensions(VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    RETURN_IF_SKIP(InitFramework());

    VkPhysicalDeviceBufferAddressFeaturesEXT buffer_device_address_features = vku::InitStructHelper();
    GetPhysicalDeviceFeatures2(buffer_device_address_features);
    buffer_device_address_features.bufferDeviceAddressCaptureReplay = VK_FALSE;

    RETURN_IF_SKIP(InitState(nullptr, &buffer_device_address_features));
    InitRenderTarget();

    VkBufferCreateInfo buffer_create_info = vku::InitStructHelper();
    buffer_create_info.size = sizeof(uint32_t);
    buffer_create_info.usage = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
    buffer_create_info.flags = VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT;
    CreateBufferTest(buffer_create_info, "VUID-VkBufferCreateInfo-flags-03338");

    buffer_create_info.flags = 0;
    VkBufferDeviceAddressCreateInfoEXT addr_ci = vku::InitStructHelper();
    addr_ci.deviceAddress = 1;
    buffer_create_info.pNext = &addr_ci;
    CreateBufferTest(buffer_create_info, "VUID-VkBufferCreateInfo-deviceAddress-02604");

    buffer_create_info.pNext = nullptr;
    vkt::Buffer buffer(*m_device, buffer_create_info, vkt::no_mem);

    VkBufferDeviceAddressInfo info = vku::InitStructHelper();
    info.buffer = buffer;

    m_errorMonitor->SetDesiredError("VUID-vkGetBufferDeviceAddress-bufferDeviceAddress-03324");
    vk::GetBufferDeviceAddressEXT(device(), &info);
    m_errorMonitor->VerifyFound();

    VkMemoryRequirements buffer_mem_reqs = {};
    vk::GetBufferMemoryRequirements(device(), buffer, &buffer_mem_reqs);
    VkMemoryAllocateInfo buffer_alloc_info = vku::InitStructHelper();
    buffer_alloc_info.allocationSize = buffer_mem_reqs.size;
    m_device->Physical().SetMemoryType(buffer_mem_reqs.memoryTypeBits, &buffer_alloc_info, 0);
    vkt::DeviceMemory buffer_mem(*m_device, buffer_alloc_info);

    vk::BindBufferMemory(device(), buffer, buffer_mem, 0);
}

TEST_F(NegativeMemory, BufferDeviceAddressEXTDisabled) {
    TEST_DESCRIPTION("Test VK_EXT_buffer_device_address.");
    AddRequiredExtensions(VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    RETURN_IF_SKIP(InitFramework());

    VkPhysicalDeviceBufferAddressFeaturesEXT buffer_device_address_features = vku::InitStructHelper();
    buffer_device_address_features.bufferDeviceAddress = VK_FALSE;
    buffer_device_address_features.bufferDeviceAddressCaptureReplay = VK_FALSE;

    RETURN_IF_SKIP(InitState(nullptr, &buffer_device_address_features));
    InitRenderTarget();

    VkBufferCreateInfo buffer_create_info = vku::InitStructHelper();
    buffer_create_info.size = sizeof(uint32_t);
    buffer_create_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
    vkt::Buffer buffer(*m_device, buffer_create_info, vkt::no_mem);

    VkBufferDeviceAddressInfo info = vku::InitStructHelper();
    info.buffer = buffer;

    m_errorMonitor->SetDesiredError("VUID-vkGetBufferDeviceAddress-bufferDeviceAddress-03324");
    m_errorMonitor->SetDesiredError("VUID-VkBufferDeviceAddressInfo-buffer-02601");
    m_errorMonitor->SetDesiredError("VUID-vkGetBufferDeviceAddress-bufferDeviceAddress-03324");
    vk::GetBufferDeviceAddressEXT(device(), &info);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, BufferDeviceAddressKHRCaptureReplayFeature) {
    SetTargetApiVersion(VK_API_VERSION_1_2);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    VkBufferCreateInfo buffer_create_info = vku::InitStructHelper();
    buffer_create_info.size = sizeof(uint32_t);
    buffer_create_info.usage = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
    buffer_create_info.flags = VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT;
    CreateBufferTest(buffer_create_info, "VUID-VkBufferCreateInfo-flags-03338");
}

TEST_F(NegativeMemory, BufferDeviceAddressKHR) {
    TEST_DESCRIPTION("Test VK_KHR_buffer_device_address.");
    SetTargetApiVersion(VK_API_VERSION_1_2);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddressCaptureReplay);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    VkBufferCreateInfo buffer_create_info = vku::InitStructHelper();
    buffer_create_info.size = sizeof(uint32_t);
    buffer_create_info.usage = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
    buffer_create_info.flags = 0;
    VkBufferOpaqueCaptureAddressCreateInfo addr_ci = vku::InitStructHelper();
    addr_ci.opaqueCaptureAddress = 1;
    buffer_create_info.pNext = &addr_ci;
    CreateBufferTest(buffer_create_info, "VUID-VkBufferCreateInfo-opaqueCaptureAddress-03337");

    buffer_create_info.pNext = nullptr;
    vkt::Buffer buffer(*m_device, buffer_create_info, vkt::no_mem);

    VkBufferDeviceAddressInfo info = vku::InitStructHelper();
    info.buffer = buffer;

    m_errorMonitor->SetDesiredError("VUID-vkGetBufferDeviceAddress-bufferDeviceAddress-03324");
    vk::GetBufferDeviceAddressKHR(device(), &info);
    m_errorMonitor->VerifyFound();

    VkMemoryRequirements buffer_mem_reqs = {};
    vk::GetBufferMemoryRequirements(device(), buffer, &buffer_mem_reqs);
    VkMemoryAllocateInfo buffer_alloc_info = vku::InitStructHelper();
    buffer_alloc_info.allocationSize = buffer_mem_reqs.size;
    m_device->Physical().SetMemoryType(buffer_mem_reqs.memoryTypeBits, &buffer_alloc_info, 0);
    vkt::DeviceMemory buffer_mem(*m_device, buffer_alloc_info);

    m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-bufferDeviceAddress-03339");
    vk::BindBufferMemory(device(), buffer, buffer_mem, 0);
    m_errorMonitor->VerifyFound();

    VkDeviceMemoryOpaqueCaptureAddressInfo mem_opaque_addr_info = vku::InitStructHelper();
    mem_opaque_addr_info.memory = buffer_mem;
    m_errorMonitor->SetDesiredError("VUID-VkDeviceMemoryOpaqueCaptureAddressInfo-memory-03336");
    vk::GetDeviceMemoryOpaqueCaptureAddressKHR(device(), &mem_opaque_addr_info);
    m_errorMonitor->VerifyFound();

    m_errorMonitor->SetDesiredError("VUID-VkDeviceMemoryOpaqueCaptureAddressInfo-memory-03336");
    vk::GetDeviceMemoryOpaqueCaptureAddressKHR(device(), &mem_opaque_addr_info);
    m_errorMonitor->VerifyFound();

    VkMemoryAllocateFlagsInfo alloc_flags = vku::InitStructHelper();
    alloc_flags.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT;
    buffer_alloc_info.pNext = &alloc_flags;
    vkt::DeviceMemory buffer_mem2(*m_device, buffer_alloc_info);

    mem_opaque_addr_info.memory = buffer_mem2;
    m_errorMonitor->SetDesiredError("VUID-vkGetDeviceMemoryOpaqueCaptureAddress-pInfo-10727");
    vk::GetDeviceMemoryOpaqueCaptureAddressKHR(device(), &mem_opaque_addr_info);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, BufferDeviceAddressKHRDisabled) {
    TEST_DESCRIPTION("Test VK_KHR_buffer_device_address.");
    SetTargetApiVersion(VK_API_VERSION_1_2);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    VkBufferCreateInfo buffer_create_info = vku::InitStructHelper();
    buffer_create_info.size = sizeof(uint32_t);
    buffer_create_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
    vkt::Buffer buffer(*m_device, buffer_create_info, vkt::no_mem);

    VkBufferDeviceAddressInfo info = vku::InitStructHelper();
    info.buffer = buffer;

    m_errorMonitor->SetDesiredError("VUID-vkGetBufferDeviceAddress-bufferDeviceAddress-03324");
    m_errorMonitor->SetDesiredError("VUID-VkBufferDeviceAddressInfo-buffer-02601");
    m_errorMonitor->SetDesiredError("VUID-vkGetBufferDeviceAddress-bufferDeviceAddress-03324");
    vk::GetBufferDeviceAddressKHR(device(), &info);
    m_errorMonitor->VerifyFound();

    m_errorMonitor->SetDesiredError("VUID-vkGetBufferOpaqueCaptureAddress-pInfo-10725");
    m_errorMonitor->SetDesiredError("VUID-VkBufferDeviceAddressInfo-buffer-02601");
    m_errorMonitor->SetDesiredError("VUID-vkGetBufferOpaqueCaptureAddress-None-03326");
    vk::GetBufferOpaqueCaptureAddressKHR(device(), &info);
    m_errorMonitor->VerifyFound();

    VkMemoryRequirements buffer_mem_reqs = {};
    vk::GetBufferMemoryRequirements(device(), buffer, &buffer_mem_reqs);
    VkMemoryAllocateInfo buffer_alloc_info = vku::InitStructHelper();
    buffer_alloc_info.allocationSize = buffer_mem_reqs.size;
    m_device->Physical().SetMemoryType(buffer_mem_reqs.memoryTypeBits, &buffer_alloc_info, 0);
    VkDeviceMemory buffer_mem;
    vk::AllocateMemory(device(), &buffer_alloc_info, NULL, &buffer_mem);
    VkDeviceMemoryOpaqueCaptureAddressInfo mem_opaque_addr_info = vku::InitStructHelper();
    mem_opaque_addr_info.memory = buffer_mem;
    m_errorMonitor->SetDesiredError("VUID-vkGetDeviceMemoryOpaqueCaptureAddress-None-03334");
    m_errorMonitor->SetDesiredError("VUID-VkDeviceMemoryOpaqueCaptureAddressInfo-memory-03336");
    vk::GetDeviceMemoryOpaqueCaptureAddressKHR(device(), &mem_opaque_addr_info);
    m_errorMonitor->VerifyFound();

    vk::FreeMemory(device(), buffer_mem, NULL);

    VkMemoryAllocateFlagsInfo alloc_flags = vku::InitStructHelper();
    alloc_flags.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT | VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT;
    buffer_alloc_info.pNext = &alloc_flags;

    m_errorMonitor->SetDesiredError("VUID-VkMemoryAllocateInfo-flags-03330");
    m_errorMonitor->SetDesiredError("VUID-VkMemoryAllocateInfo-flags-03331");
    vk::AllocateMemory(device(), &buffer_alloc_info, NULL, &buffer_mem);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, MemoryType) {
    // Attempts to allocate from a memory type that doesn't exist

    RETURN_IF_SKIP(Init());
    VkPhysicalDeviceMemoryProperties memory_info;
    vk::GetPhysicalDeviceMemoryProperties(Gpu(), &memory_info);

    m_errorMonitor->SetDesiredError("VUID-vkAllocateMemory-pAllocateInfo-01714");

    VkMemoryAllocateInfo mem_alloc = vku::InitStructHelper();
    mem_alloc.memoryTypeIndex = memory_info.memoryTypeCount;
    mem_alloc.allocationSize = 4;

    VkDeviceMemory mem;
    vk::AllocateMemory(device(), &mem_alloc, NULL, &mem);

    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, AllocationBeyondHeapSize) {
    // Attempts to allocate a single piece of memory that's larger than the heap size

    RETURN_IF_SKIP(Init());
    VkPhysicalDeviceMemoryProperties memory_info;
    vk::GetPhysicalDeviceMemoryProperties(Gpu(), &memory_info);

    // This can be triggered due to the extremely large allocation
    m_errorMonitor->SetAllowedFailureMsg("UNASSIGNED-vkAllocateMemory-maxMemoryAllocationSize");

    m_errorMonitor->SetDesiredError("VUID-vkAllocateMemory-pAllocateInfo-01713");

    VkMemoryAllocateInfo mem_alloc = vku::InitStructHelper();
    mem_alloc.memoryTypeIndex = 0;
    mem_alloc.allocationSize = memory_info.memoryHeaps[memory_info.memoryTypes[0].heapIndex].size + 1;

    VkDeviceMemory mem;
    vk::AllocateMemory(device(), &mem_alloc, NULL, &mem);

    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, DeviceCoherentMemoryDisabledAMD) {
    // Attempts to allocate device coherent memory without enabling the extension/feature
    AddRequiredExtensions(VK_AMD_DEVICE_COHERENT_MEMORY_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    if (IsPlatformMockICD()) {
        GTEST_SKIP() << "Test not supported by MockICD, does not support the necessary memory type";
    }

    // Find a memory type that includes the device coherent memory property
    VkPhysicalDeviceMemoryProperties memory_info;
    vk::GetPhysicalDeviceMemoryProperties(Gpu(), &memory_info);
    uint32_t deviceCoherentMemoryTypeIndex = memory_info.memoryTypeCount;  // Set to an invalid value just in case

    for (uint32_t i = 0; i < memory_info.memoryTypeCount; ++i) {
        if ((memory_info.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD) != 0) {
            deviceCoherentMemoryTypeIndex = i;
            break;
        }
    }

    if (deviceCoherentMemoryTypeIndex == memory_info.memoryTypeCount) {
        GTEST_SKIP() << "Valid memory type index not found";
    }

    m_errorMonitor->SetDesiredError("VUID-vkAllocateMemory-deviceCoherentMemory-02790");

    VkMemoryAllocateInfo mem_alloc = vku::InitStructHelper();
    mem_alloc.memoryTypeIndex = deviceCoherentMemoryTypeIndex;
    mem_alloc.allocationSize = 4;

    VkDeviceMemory mem;
    vk::AllocateMemory(device(), &mem_alloc, NULL, &mem);

    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, DedicatedAllocation) {
    TEST_DESCRIPTION("Create invalid requests to dedicated allocation of memory");

    // Both VK_KHR_dedicated_allocation and VK_KHR_sampler_ycbcr_conversion supported in 1.1
    // Quicke to set 1.1 then check all extensions in 1.0
    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredFeature(vkt::Feature::sparseBinding);
    RETURN_IF_SKIP(Init());

    const VkFormat disjoint_format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
    const VkFormat normal_format = VK_FORMAT_R8G8B8A8_UNORM;
    VkFormatProperties format_properties;
    vk::GetPhysicalDeviceFormatProperties(m_device->Physical(), disjoint_format, &format_properties);

    bool sparse_support = (m_device->Physical().Features().sparseBinding == VK_TRUE);
    bool disjoint_support = ((format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_DISJOINT_BIT) != 0);

    VkBufferCreateInfo buffer_create_info = vku::InitStructHelper();
    buffer_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
    buffer_create_info.size = 2048;

    VkImageCreateInfo image_create_info =
        vkt::Image::ImageCreateInfo2D(64, 64, 1, 1, normal_format, VK_IMAGE_USAGE_TRANSFER_SRC_BIT);

    // Create Images and Buffers without any memory backing
    VkImage normal_image = VK_NULL_HANDLE;
    vk::CreateImage(device(), &image_create_info, nullptr, &normal_image);

    VkBuffer normal_buffer = VK_NULL_HANDLE;
    vk::CreateBuffer(device(), &buffer_create_info, nullptr, &normal_buffer);

    VkImage sparse_image = VK_NULL_HANDLE;
    VkBuffer sparse_buffer = VK_NULL_HANDLE;
    if (sparse_support == true) {
        image_create_info.flags = VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
        vk::CreateImage(device(), &image_create_info, nullptr, &sparse_image);
        buffer_create_info.flags = VK_BUFFER_CREATE_SPARSE_BINDING_BIT;
        vk::CreateBuffer(device(), &buffer_create_info, nullptr, &sparse_buffer);
    }

    VkImage disjoint_image = VK_NULL_HANDLE;
    if (disjoint_support == true) {
        image_create_info.format = disjoint_format;
        image_create_info.flags = VK_IMAGE_CREATE_DISJOINT_BIT;
        vk::CreateImage(device(), &image_create_info, nullptr, &disjoint_image);
    }

    VkDeviceMemory device_memory;
    VkMemoryDedicatedAllocateInfo dedicated_allocate_info = vku::InitStructHelper();
    VkMemoryAllocateInfo memory_allocate_info = vku::InitStructHelper(&dedicated_allocate_info);
    memory_allocate_info.memoryTypeIndex = 0;
    memory_allocate_info.allocationSize = 64;

    // Both image and buffer set in dedicated allocation
    dedicated_allocate_info.image = normal_image;
    dedicated_allocate_info.buffer = normal_buffer;
    m_errorMonitor->SetDesiredError("VUID-VkMemoryDedicatedAllocateInfo-image-01432");
    vk::AllocateMemory(device(), &memory_allocate_info, NULL, &device_memory);
    m_errorMonitor->VerifyFound();

    if (sparse_support == true) {
        VkMemoryRequirements sparse_image_memory_req;
        vk::GetImageMemoryRequirements(device(), sparse_image, &sparse_image_memory_req);
        VkMemoryRequirements sparse_buffer_memory_req;
        vk::GetBufferMemoryRequirements(device(), sparse_buffer, &sparse_buffer_memory_req);

        dedicated_allocate_info.image = sparse_image;
        dedicated_allocate_info.buffer = VK_NULL_HANDLE;
        memory_allocate_info.allocationSize = sparse_image_memory_req.size;
        m_errorMonitor->SetDesiredError("VUID-VkMemoryDedicatedAllocateInfo-image-01434");
        vk::AllocateMemory(device(), &memory_allocate_info, NULL, &device_memory);
        m_errorMonitor->VerifyFound();

        dedicated_allocate_info.image = VK_NULL_HANDLE;
        dedicated_allocate_info.buffer = sparse_buffer;
        memory_allocate_info.allocationSize = sparse_buffer_memory_req.size;
        m_errorMonitor->SetDesiredError("VUID-VkMemoryDedicatedAllocateInfo-buffer-01436");
        vk::AllocateMemory(device(), &memory_allocate_info, NULL, &device_memory);
        m_errorMonitor->VerifyFound();
    }

    if (disjoint_support == true) {
        VkImagePlaneMemoryRequirementsInfo image_plane_req = vku::InitStructHelper();
        image_plane_req.planeAspect = VK_IMAGE_ASPECT_PLANE_2_BIT;
        VkImageMemoryRequirementsInfo2 mem_req_info2 = vku::InitStructHelper(&image_plane_req);
        mem_req_info2.image = disjoint_image;
        VkMemoryRequirements2 mem_req2 = vku::InitStructHelper();

        vk::GetImageMemoryRequirements2(device(), &mem_req_info2, &mem_req2);

        dedicated_allocate_info.image = disjoint_image;
        dedicated_allocate_info.buffer = VK_NULL_HANDLE;
        memory_allocate_info.allocationSize = mem_req2.memoryRequirements.size;
        m_errorMonitor->SetDesiredError("VUID-VkMemoryDedicatedAllocateInfo-image-01797");
        vk::AllocateMemory(device(), &memory_allocate_info, NULL, &device_memory);
        m_errorMonitor->VerifyFound();
    }

    VkMemoryRequirements normal_image_memory_req;
    vk::GetImageMemoryRequirements(device(), normal_image, &normal_image_memory_req);
    VkMemoryRequirements normal_buffer_memory_req;
    vk::GetBufferMemoryRequirements(device(), normal_buffer, &normal_buffer_memory_req);

    // Set allocation size to be not equal to memory requirement
    memory_allocate_info.allocationSize = normal_image_memory_req.size - 1;
    dedicated_allocate_info.image = normal_image;
    dedicated_allocate_info.buffer = VK_NULL_HANDLE;

    m_errorMonitor->SetDesiredError("VUID-VkMemoryDedicatedAllocateInfo-image-02964");
    vk::AllocateMemory(device(), &memory_allocate_info, NULL, &device_memory);
    m_errorMonitor->VerifyFound();

    memory_allocate_info.allocationSize = normal_buffer_memory_req.size - 1;
    dedicated_allocate_info.image = VK_NULL_HANDLE;
    dedicated_allocate_info.buffer = normal_buffer;
    m_errorMonitor->SetDesiredError("VUID-VkMemoryDedicatedAllocateInfo-buffer-02965");
    vk::AllocateMemory(device(), &memory_allocate_info, NULL, &device_memory);
    m_errorMonitor->VerifyFound();

    vk::DestroyImage(device(), normal_image, nullptr);
    vk::DestroyBuffer(device(), normal_buffer, nullptr);
    if (sparse_support == true) {
        vk::DestroyImage(device(), sparse_image, nullptr);
        vk::DestroyBuffer(device(), sparse_buffer, nullptr);
    }
    if (disjoint_support == true) {
        vk::DestroyImage(device(), disjoint_image, nullptr);
    }
}

TEST_F(NegativeMemory, MemoryRequirements) {
    TEST_DESCRIPTION("Create invalid requests to image and buffer memory requirements.");
    AddRequiredExtensions(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());
    // Need to make sure disjoint is supported for format
    // Also need to support an arbitrary image usage feature
    VkFormatProperties format_properties;
    vk::GetPhysicalDeviceFormatProperties(m_device->Physical(), VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, &format_properties);
    if (!((format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_DISJOINT_BIT) &&
          (format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))) {
        GTEST_SKIP() << "test requires disjoint/sampled feature bit on format";
    }
    VkImageCreateInfo image_create_info = vku::InitStructHelper();
    image_create_info.imageType = VK_IMAGE_TYPE_2D;
    image_create_info.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
    image_create_info.extent = {64, 64, 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 = VK_IMAGE_CREATE_DISJOINT_BIT;

    VkImage image;
    VkResult err = vk::CreateImage(device(), &image_create_info, NULL, &image);
    ASSERT_EQ(VK_SUCCESS, err);

    m_errorMonitor->SetDesiredError("VUID-vkGetImageMemoryRequirements-image-01588");
    VkMemoryRequirements memory_requirements;
    vk::GetImageMemoryRequirements(device(), image, &memory_requirements);
    m_errorMonitor->VerifyFound();

    VkImageMemoryRequirementsInfo2 mem_req_info2 = vku::InitStructHelper();
    mem_req_info2.image = image;
    VkMemoryRequirements2 mem_req2 = vku::InitStructHelper();

    m_errorMonitor->SetDesiredError("VUID-VkImageMemoryRequirementsInfo2-image-01589");
    vk::GetImageMemoryRequirements2KHR(device(), &mem_req_info2, &mem_req2);
    m_errorMonitor->VerifyFound();

    // Point to a 3rd plane for a 2-plane format
    VkImagePlaneMemoryRequirementsInfo image_plane_req = vku::InitStructHelper();
    image_plane_req.planeAspect = VK_IMAGE_ASPECT_PLANE_2_BIT;
    mem_req_info2.pNext = &image_plane_req;
    mem_req_info2.image = image;

    m_errorMonitor->SetDesiredError("VUID-VkImagePlaneMemoryRequirementsInfo-planeAspect-02281");
    vk::GetImageMemoryRequirements2KHR(device(), &mem_req_info2, &mem_req2);
    m_errorMonitor->VerifyFound();

    // Test with a non planar image aspect also
    image_plane_req.planeAspect = VK_IMAGE_ASPECT_COLOR_BIT;
    mem_req_info2.pNext = &image_plane_req;
    mem_req_info2.image = image;

    m_errorMonitor->SetDesiredError("VUID-VkImagePlaneMemoryRequirementsInfo-planeAspect-02281");
    vk::GetImageMemoryRequirements2KHR(device(), &mem_req_info2, &mem_req2);
    m_errorMonitor->VerifyFound();

    vk::DestroyImage(device(), image, nullptr);

    // Recreate image without Disjoint bit
    image_create_info.flags = 0;
    err = vk::CreateImage(device(), &image_create_info, NULL, &image);
    ASSERT_EQ(VK_SUCCESS, err);

    image_plane_req.planeAspect = VK_IMAGE_ASPECT_PLANE_0_BIT;
    mem_req_info2.pNext = &image_plane_req;
    mem_req_info2.image = image;

    m_errorMonitor->SetDesiredError("VUID-VkImageMemoryRequirementsInfo2-image-01590");
    vk::GetImageMemoryRequirements2KHR(device(), &mem_req_info2, &mem_req2);
    m_errorMonitor->VerifyFound();

    vk::DestroyImage(device(), image, nullptr);

    // Recreate image with single plane format and with Disjoint bit
    image_create_info.flags = 0;
    image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
    err = vk::CreateImage(device(), &image_create_info, NULL, &image);
    ASSERT_EQ(VK_SUCCESS, err);

    image_plane_req.planeAspect = VK_IMAGE_ASPECT_PLANE_0_BIT;
    mem_req_info2.pNext = &image_plane_req;
    mem_req_info2.image = image;

    // Disjoint bit isn't set as likely not even supported by non-planar format
    m_errorMonitor->SetUnexpectedError("VUID-VkImageMemoryRequirementsInfo2-image-01590");
    m_errorMonitor->SetDesiredError("VUID-VkImageMemoryRequirementsInfo2-image-02280");
    vk::GetImageMemoryRequirements2KHR(device(), &mem_req_info2, &mem_req2);
    m_errorMonitor->VerifyFound();

    vk::DestroyImage(device(), image, nullptr);
}

TEST_F(NegativeMemory, MemoryAllocatepNextChain) {
    AddRequiredExtensions(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
    AddRequiredExtensions(VK_NV_EXTERNAL_MEMORY_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());
    VkDeviceMemory mem;
    VkMemoryAllocateInfo mem_alloc = vku::InitStructHelper();
    mem_alloc.memoryTypeIndex = 0;
    mem_alloc.allocationSize = 4;

    // pNext chain includes both VkExportMemoryAllocateInfo and VkExportMemoryAllocateInfoNV
    VkExportMemoryAllocateInfoNV export_memory_info_nv = vku::InitStructHelper();
    export_memory_info_nv.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV;

    VkExportMemoryAllocateInfo export_memory_info = vku::InitStructHelper(&export_memory_info_nv);
    export_memory_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;

    m_errorMonitor->SetDesiredError("VUID-VkMemoryAllocateInfo-pNext-00640");
    mem_alloc.pNext = &export_memory_info;
    vk::AllocateMemory(device(), &mem_alloc, NULL, &mem);
    m_errorMonitor->VerifyFound();
}

#ifdef VK_USE_PLATFORM_WIN32_KHR
TEST_F(NegativeMemory, MemoryAllocatepNextChainWin32) {
    AddRequiredExtensions(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME);
    AddRequiredExtensions(VK_NV_EXTERNAL_MEMORY_EXTENSION_NAME);
    AddRequiredExtensions(VK_NV_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());
    VkDeviceMemory mem;
    VkMemoryAllocateInfo mem_alloc = vku::InitStructHelper();
    mem_alloc.memoryTypeIndex = 0;
    mem_alloc.allocationSize = 4;

    // pNext chain includes both VkExportMemoryAllocateInfo and VkExportMemoryWin32HandleInfoNV
    {
        VkExportMemoryWin32HandleInfoNV export_memory_info_win32_nv = vku::InitStructHelper();
        export_memory_info_win32_nv.pAttributes = nullptr;
        export_memory_info_win32_nv.dwAccess = 0;

        VkExportMemoryAllocateInfo export_memory_info = vku::InitStructHelper(&export_memory_info_win32_nv);
        export_memory_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;

        m_errorMonitor->SetDesiredError("VUID-VkMemoryAllocateInfo-pNext-00640");
        mem_alloc.pNext = &export_memory_info;
        vk::AllocateMemory(device(), &mem_alloc, NULL, &mem);
        m_errorMonitor->VerifyFound();
    }
    // pNext chain includes both VkImportMemoryWin32HandleInfoKHR and VkImportMemoryWin32HandleInfoNV
    {
        VkImportMemoryWin32HandleInfoKHR import_memory_info_win32_khr = vku::InitStructHelper();
        import_memory_info_win32_khr.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;

        VkImportMemoryWin32HandleInfoNV import_memory_info_win32_nv = vku::InitStructHelper(&import_memory_info_win32_khr);
        import_memory_info_win32_nv.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV;

        m_errorMonitor->SetUnexpectedError("VUID-VkMemoryAllocateInfo-None-06657");
        m_errorMonitor->SetDesiredError("VUID-VkMemoryAllocateInfo-pNext-00641");
        mem_alloc.pNext = &import_memory_info_win32_nv;
        vk::AllocateMemory(device(), &mem_alloc, NULL, &mem);
        m_errorMonitor->VerifyFound();
    }
}
#endif  // VK_USE_PLATFORM_WIN32_KHR

TEST_F(NegativeMemory, DeviceImageMemoryRequirementsSwapchain) {
    TEST_DESCRIPTION("Validate usage of VkDeviceImageMemoryRequirementsKHR.");

    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_KHR_MAINTENANCE_4_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    VkImageSwapchainCreateInfoKHR image_swapchain_create_info = vku::InitStructHelper();
    image_swapchain_create_info.swapchain = m_swapchain;

    VkImageCreateInfo image_create_info = vku::InitStructHelper(&image_swapchain_create_info);
    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.samples = VK_SAMPLE_COUNT_1_BIT;
    image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
    image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
    image_create_info.arrayLayers = 1;

    VkDeviceImageMemoryRequirementsKHR device_image_memory_requirements = vku::InitStructHelper();
    device_image_memory_requirements.pCreateInfo = &image_create_info;
    device_image_memory_requirements.planeAspect = VK_IMAGE_ASPECT_COLOR_BIT;

    VkMemoryRequirements2 memory_requirements = vku::InitStructHelper();

    m_errorMonitor->SetDesiredError("VUID-VkDeviceImageMemoryRequirements-pCreateInfo-06416");
    vk::GetDeviceImageMemoryRequirementsKHR(device(), &device_image_memory_requirements, &memory_requirements);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, DeviceImageMemoryRequirementsDisjoint) {
    TEST_DESCRIPTION("Validate usage of VkDeviceImageMemoryRequirementsKHR.");

    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_KHR_MAINTENANCE_4_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    const VkFormat format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
    VkFormatProperties format_properties;
    vk::GetPhysicalDeviceFormatProperties(m_device->Physical(), format, &format_properties);
    if ((format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_DISJOINT_BIT) == 0) {
        GTEST_SKIP() << "Test requires disjoint support extensions";
    }

    VkImageCreateInfo image_create_info = vku::InitStructHelper();
    image_create_info.imageType = VK_IMAGE_TYPE_2D;
    image_create_info.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
    image_create_info.flags = VK_IMAGE_CREATE_DISJOINT_BIT;
    image_create_info.extent = {32, 32, 1};
    image_create_info.mipLevels = 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_SRC_BIT;
    image_create_info.arrayLayers = 1;

    VkDeviceImageMemoryRequirementsKHR device_image_memory_requirements = vku::InitStructHelper();
    device_image_memory_requirements.pCreateInfo = &image_create_info;
    device_image_memory_requirements.planeAspect = VK_IMAGE_ASPECT_NONE;

    VkMemoryRequirements2 memory_requirements = vku::InitStructHelper();

    m_errorMonitor->SetDesiredError("VUID-VkDeviceImageMemoryRequirements-pCreateInfo-06417");
    vk::GetDeviceImageMemoryRequirementsKHR(device(), &device_image_memory_requirements, &memory_requirements);
    m_errorMonitor->VerifyFound();

    device_image_memory_requirements.planeAspect = VK_IMAGE_ASPECT_PLANE_2_BIT;
    m_errorMonitor->SetDesiredError("VUID-VkDeviceImageMemoryRequirements-pCreateInfo-06419");
    vk::GetDeviceImageMemoryRequirementsKHR(device(), &device_image_memory_requirements, &memory_requirements);
    m_errorMonitor->VerifyFound();

    // valid
    device_image_memory_requirements.planeAspect = VK_IMAGE_ASPECT_PLANE_1_BIT;
    vk::GetDeviceImageMemoryRequirementsKHR(device(), &device_image_memory_requirements, &memory_requirements);
}

TEST_F(NegativeMemory, BindBufferMemoryDeviceGroup) {
    TEST_DESCRIPTION("Test VkBindBufferMemoryDeviceGroupInfo.");

    SetTargetApiVersion(VK_API_VERSION_1_1);
    RETURN_IF_SKIP(InitFramework());

    uint32_t physical_device_group_count = 0;
    vk::EnumeratePhysicalDeviceGroups(instance(), &physical_device_group_count, nullptr);

    if (physical_device_group_count == 0) {
        GTEST_SKIP() << "physical_device_group_count is 0";
    }
    std::vector<VkPhysicalDeviceGroupProperties> physical_device_group(physical_device_group_count,
                                                                       {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES});
    vk::EnumeratePhysicalDeviceGroups(instance(), &physical_device_group_count, physical_device_group.data());
    VkDeviceGroupDeviceCreateInfo create_device_pnext = vku::InitStructHelper();
    create_device_pnext.physicalDeviceCount = 0;
    create_device_pnext.pPhysicalDevices = nullptr;
    for (const auto& dg : physical_device_group) {
        if (dg.physicalDeviceCount > 1) {
            create_device_pnext.physicalDeviceCount = dg.physicalDeviceCount;
            create_device_pnext.pPhysicalDevices = dg.physicalDevices;
            break;
        }
    }
    if (create_device_pnext.pPhysicalDevices) {
        RETURN_IF_SKIP(InitState(nullptr, &create_device_pnext));
    } else {
        GTEST_SKIP() << "Test requires a physical device group with more than 1 device";
    }

    auto buffer_info = vkt::Buffer::CreateInfo(4096, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
    vkt::Buffer buffer(*m_device, buffer_info, vkt::no_mem);

    VkMemoryRequirements buffer_mem_reqs;
    vk::GetBufferMemoryRequirements(device(), buffer, &buffer_mem_reqs);
    VkMemoryAllocateInfo buffer_alloc_info = vku::InitStructHelper();
    buffer_alloc_info.memoryTypeIndex = 0;
    buffer_alloc_info.allocationSize = buffer_mem_reqs.size;

    vkt::DeviceMemory buffer_memory(*m_device, buffer_alloc_info);

    std::vector<uint32_t> device_indices(create_device_pnext.physicalDeviceCount);

    VkBindBufferMemoryDeviceGroupInfo bind_buffer_memory_device_group = vku::InitStructHelper();
    bind_buffer_memory_device_group.deviceIndexCount = 1;
    bind_buffer_memory_device_group.pDeviceIndices = device_indices.data();

    VkBindBufferMemoryInfo bind_buffer_info = vku::InitStructHelper(&bind_buffer_memory_device_group);
    bind_buffer_info.buffer = buffer;
    bind_buffer_info.memory = buffer_memory;
    bind_buffer_info.memoryOffset = 0;

    m_errorMonitor->SetDesiredError("VUID-VkBindBufferMemoryDeviceGroupInfo-deviceIndexCount-01606");
    vk::BindBufferMemory2(device(), 1, &bind_buffer_info);
    m_errorMonitor->VerifyFound();

    bind_buffer_memory_device_group.deviceIndexCount = create_device_pnext.physicalDeviceCount;
    device_indices[0] = create_device_pnext.physicalDeviceCount;
    m_errorMonitor->SetDesiredError("VUID-VkBindBufferMemoryDeviceGroupInfo-pDeviceIndices-01607");
    vk::BindBufferMemory2(device(), 1, &bind_buffer_info);
    m_errorMonitor->VerifyFound();
    device_indices[0] = 0;

    VkImageCreateInfo image_create_info =
        vkt::Image::ImageCreateInfo2D(32, 32, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
    vkt::Image image(*m_device, image_create_info, vkt::no_mem);

    VkMemoryRequirements image_mem_reqs;
    vk::GetBufferMemoryRequirements(device(), buffer, &image_mem_reqs);
    VkMemoryAllocateInfo image_alloc_info = vku::InitStructHelper();
    image_alloc_info.memoryTypeIndex = 0;
    image_alloc_info.allocationSize = image_mem_reqs.size;

    vkt::DeviceMemory image_memory(*m_device, image_alloc_info);

    VkBindImageMemoryDeviceGroupInfo bind_image_memory_device_group = vku::InitStructHelper();
    bind_image_memory_device_group.deviceIndexCount = 1;
    bind_image_memory_device_group.pDeviceIndices = device_indices.data();

    VkBindImageMemoryInfo bind_image_info = vku::InitStructHelper(&bind_image_memory_device_group);
    bind_image_info.image = image;
    bind_image_info.memory = image_memory;
    bind_image_info.memoryOffset = 0;

    m_errorMonitor->SetDesiredError("VUID-VkBindImageMemoryDeviceGroupInfo-deviceIndexCount-01634");
    vk::BindImageMemory2(device(), 1, &bind_image_info);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, MemoryPriorityOutOfRange) {
    TEST_DESCRIPTION("Allocate memory with invalid priority.");

    AddRequiredExtensions(VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    VkMemoryPriorityAllocateInfoEXT priority = vku::InitStructHelper();
    priority.priority = 2.0f;

    VkMemoryAllocateInfo memory_ai = vku::InitStructHelper(&priority);
    memory_ai.allocationSize = 0x100000;
    memory_ai.memoryTypeIndex = 0;

    VkDeviceMemory memory;
    m_errorMonitor->SetDesiredError("VUID-VkMemoryPriorityAllocateInfoEXT-priority-02602");
    vk::AllocateMemory(*m_device, &memory_ai, nullptr, &memory);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, SetDeviceMemoryPriority) {
    AddRequiredExtensions(VK_EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    vkt::Buffer buffer(*m_device, vkt::Buffer::CreateInfo(1024, VK_BUFFER_USAGE_TRANSFER_DST_BIT), vkt::no_mem);

    vkt::DeviceMemory buffer_memory(*m_device, vkt::DeviceMemory::GetResourceAllocInfo(*m_device, buffer.MemoryRequirements(), 0));

    m_errorMonitor->SetDesiredError("VUID-vkSetDeviceMemoryPriorityEXT-priority-06258");
    vk::SetDeviceMemoryPriorityEXT(*m_device, buffer_memory, -0.01f);
    m_errorMonitor->VerifyFound();

    m_errorMonitor->SetDesiredError("VUID-vkSetDeviceMemoryPriorityEXT-priority-06258");
    vk::SetDeviceMemoryPriorityEXT(*m_device, buffer_memory, 1.01f);
    m_errorMonitor->VerifyFound();

    vk::SetDeviceMemoryPriorityEXT(*m_device, buffer_memory, 1.0f);
}

TEST_F(NegativeMemory, BadMemoryBindMemory2) {
    TEST_DESCRIPTION("Bind bogus memory for VkBindImageMemoryInfo::memory ");
    AddRequiredExtensions(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    auto image_ci = vkt::Image::ImageCreateInfo2D(32, 32, 1, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT);
    vkt::Image image(*m_device, image_ci, vkt::no_mem);

    VkDeviceMemory bad_memory = CastToHandle<VkDeviceMemory, uintptr_t>(0xbaadbeef);
    VkBindImageMemoryInfo image_bind_info = vku::InitStructHelper();
    image_bind_info.image = image;
    image_bind_info.memory = bad_memory;
    image_bind_info.memoryOffset = 0;

    m_errorMonitor->SetDesiredError("VUID-VkBindImageMemoryInfo-pNext-01632");
    vk::BindImageMemory2KHR(device(), 1, &image_bind_info);
    m_errorMonitor->VerifyFound();
}

// TODO - Need a way to trigger Test ICD to fail call
TEST_F(NegativeMemory, DISABLED_PartialBoundBuffer) {
    TEST_DESCRIPTION("https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/5527");
    AddRequiredExtensions(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    if (!IsPlatformMockICD()) {
        GTEST_SKIP() << "Test needs to force a failure";
    }

    VkBufferCreateInfo buffer_create_info = vku::InitStructHelper();
    buffer_create_info.size = 1024;
    buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
    vkt::Buffer buffer_0(*m_device, buffer_create_info, vkt::no_mem);
    vkt::Buffer buffer_1(*m_device, buffer_create_info, vkt::no_mem);

    VkMemoryAllocateInfo alloc_info = vkt::DeviceMemory::GetResourceAllocInfo(*m_device, buffer_0.MemoryRequirements(), 0);
    vkt::DeviceMemory buffer_memory(*m_device, alloc_info);

    VkBindBufferMemoryInfo bind_buffer_infos[2];
    bind_buffer_infos[0] = vku::InitStructHelper();
    bind_buffer_infos[0].buffer = buffer_0;
    bind_buffer_infos[0].memory = buffer_memory;
    bind_buffer_infos[1] = vku::InitStructHelper();
    bind_buffer_infos[1].buffer = buffer_1;
    bind_buffer_infos[1].memory = buffer_memory;

    VkResult result = vk::BindBufferMemory2KHR(device(), 2, bind_buffer_infos);
    if (result == VK_SUCCESS) {
        GTEST_SKIP() << "Test needs a to fail call";
    }

    m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-buffer-07459");
    vk::BindBufferMemory(device(), buffer_0, buffer_memory, 0);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, MaxMemoryAllocationSize) {
    SetTargetApiVersion(VK_API_VERSION_1_2);
    RETURN_IF_SKIP(Init());
    if (!IsPlatformMockICD()) {
        GTEST_SKIP() << "Can't test well on real hardware";
    }

    VkPhysicalDeviceVulkan11Properties props11 = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(props11);

    VkMemoryAllocateInfo alloc_info = vku::InitStructHelper();
    alloc_info.allocationSize = props11.maxMemoryAllocationSize + 64;

    m_errorMonitor->SetAllowedFailureMsg("VUID-vkAllocateMemory-pAllocateInfo-01713");  // need to bypass stateless
    m_errorMonitor->SetDesiredError("UNASSIGNED-vkAllocateMemory-maxMemoryAllocationSize");
    vkt::DeviceMemory memory(*m_device, alloc_info);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, RequiredDedicatedAllocationBuffer) {
    SetTargetApiVersion(VK_API_VERSION_1_1);
    RETURN_IF_SKIP(Init());

    auto buffer_info = vkt::Buffer::CreateInfo(4096, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
    vkt::Buffer buffer(*m_device, buffer_info, vkt::no_mem);
    vkt::Buffer buffer2(*m_device, buffer_info, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);

    VkBufferMemoryRequirementsInfo2 buffer_memory_requirements_info = vku::InitStructHelper();
    buffer_memory_requirements_info.buffer = buffer;

    VkMemoryDedicatedRequirements memory_dedicated_requirements = vku::InitStructHelper();
    VkMemoryRequirements2 memory_requirements = vku::InitStructHelper(&memory_dedicated_requirements);
    vk::GetBufferMemoryRequirements2(device(), &buffer_memory_requirements_info, &memory_requirements);
    // TODO - hard to get this required for buffer, would be good to have way for TestICD to force it on for this test
    if (!memory_dedicated_requirements.requiresDedicatedAllocation) {
        GTEST_SKIP() << "requiresDedicatedAllocation is false";
    }

    {
        VkMemoryAllocateInfo memory_info = vku::InitStructHelper();
        memory_info.allocationSize = memory_requirements.memoryRequirements.size;
        bool pass = m_device->Physical().SetMemoryType(memory_requirements.memoryRequirements.memoryTypeBits, &memory_info,
                                                       VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
        ASSERT_TRUE(pass);
        vkt::DeviceMemory device_memory(*m_device, memory_info);

        VkBindBufferMemoryInfo bind_buffer_memory_info = vku::InitStructHelper();
        bind_buffer_memory_info.buffer = buffer;
        bind_buffer_memory_info.memory = device_memory;
        bind_buffer_memory_info.memoryOffset = 0u;
        m_errorMonitor->SetDesiredError("VUID-VkBindBufferMemoryInfo-buffer-01444");
        vk::BindBufferMemory2(device(), 1u, &bind_buffer_memory_info);
        m_errorMonitor->VerifyFound();
    }

    {
        VkMemoryDedicatedAllocateInfo memory_dedicated_allocate_info = vku::InitStructHelper();
        memory_dedicated_allocate_info.buffer = buffer2;
        VkMemoryAllocateInfo memory_info = vku::InitStructHelper(&memory_dedicated_allocate_info);
        memory_info.allocationSize = memory_requirements.memoryRequirements.size;
        bool pass = m_device->Physical().SetMemoryType(memory_requirements.memoryRequirements.memoryTypeBits, &memory_info,
                                                       VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
        ASSERT_TRUE(pass);
        vkt::DeviceMemory device_memory(*m_device, memory_info);

        m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-memory-01508");
        m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-buffer-01444");
        vk::BindBufferMemory(device(), buffer, device_memory, 0u);
        m_errorMonitor->VerifyFound();
    }
}

TEST_F(NegativeMemory, MapMemoryWithMapPlacedFlag) {
    TEST_DESCRIPTION("Test vkCmdUpdateBuffer");

    AddRequiredExtensions(VK_EXT_MAP_MEMORY_PLACED_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    const VkDeviceSize allocation_size = 8192u;

    VkMemoryAllocateInfo memory_info = vku::InitStructHelper();
    memory_info.allocationSize = allocation_size;

    bool pass = m_device->Physical().SetMemoryType(vvl::kU32Max, &memory_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
    ASSERT_TRUE(pass);

    vkt::DeviceMemory memory(*m_device, memory_info);

    void* data;
    m_errorMonitor->SetDesiredError("VUID-vkMapMemory-flags-09568");
    vk::MapMemory(device(), memory, 0u, 4u, VK_MEMORY_MAP_PLACED_BIT_EXT, &data);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeMemory, RequiredDedicatedAllocationImage) {
    SetTargetApiVersion(VK_API_VERSION_1_1);
    RETURN_IF_SKIP(Init());

    VkImageCreateInfo image_create_info =
        vkt::Image::ImageCreateInfo2D(32u, 32u, 1u, 1u, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT);
    vkt::Image image(*m_device, image_create_info, vkt::no_mem);

    vkt::Image image2(*m_device, image_create_info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

    VkImageMemoryRequirementsInfo2 image_memory_requirements_info = vku::InitStructHelper();
    image_memory_requirements_info.image = image;

    VkMemoryDedicatedRequirements memory_dedicated_requirements = vku::InitStructHelper();

    VkMemoryRequirements2 memory_requirements = vku::InitStructHelper(&memory_dedicated_requirements);
    vk::GetImageMemoryRequirements2(device(), &image_memory_requirements_info, &memory_requirements);

    if (!memory_dedicated_requirements.requiresDedicatedAllocation) {
        GTEST_SKIP() << "requiresDedicatedAllocation is false";
    }

    {
        VkMemoryAllocateInfo memory_info = vku::InitStructHelper();
        memory_info.allocationSize = memory_requirements.memoryRequirements.size;
        bool pass = m_device->Physical().SetMemoryType(memory_requirements.memoryRequirements.memoryTypeBits, &memory_info,
                                                       VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
        ASSERT_TRUE(pass);
        vkt::DeviceMemory device_memory(*m_device, memory_info);

        VkBindImageMemoryInfo bind_image_memory_info = vku::InitStructHelper();
        bind_image_memory_info.image = image;
        bind_image_memory_info.memory = device_memory;
        bind_image_memory_info.memoryOffset = 0u;
        m_errorMonitor->SetDesiredError("VUID-VkBindImageMemoryInfo-image-01445");
        vk::BindImageMemory2(device(), 1u, &bind_image_memory_info);
        m_errorMonitor->VerifyFound();
    }

    {
        VkMemoryDedicatedAllocateInfo memory_dedicated_allocate_info = vku::InitStructHelper();
        memory_dedicated_allocate_info.image = image2;
        VkMemoryAllocateInfo memory_info = vku::InitStructHelper(&memory_dedicated_allocate_info);
        memory_info.allocationSize = memory_requirements.memoryRequirements.size;
        bool pass = m_device->Physical().SetMemoryType(memory_requirements.memoryRequirements.memoryTypeBits, &memory_info,
                                                       VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
        ASSERT_TRUE(pass);
        vkt::DeviceMemory device_memory(*m_device, memory_info);

        m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-memory-02628");
        m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-image-01445");
        vk::BindImageMemory(device(), image, device_memory, 0u);
        m_errorMonitor->VerifyFound();
    }
}

TEST_F(NegativeMemory, DedicatedAllocationWrongObject) {
    SetTargetApiVersion(VK_API_VERSION_1_1);
    RETURN_IF_SKIP(Init());

    auto buffer_info = vkt::Buffer::CreateInfo(4096u, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
    vkt::Buffer buffer(*m_device, buffer_info, vkt::no_mem);

    auto image_info = vkt::Image::ImageCreateInfo2D(32u, 32u, 1u, 1u, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT);
    vkt::Image image(*m_device, image_info, vkt::no_mem);

    VkBufferMemoryRequirementsInfo2 buffer_memory_requirements_info = vku::InitStructHelper();
    buffer_memory_requirements_info.buffer = buffer;
    VkMemoryDedicatedRequirements buffer_memory_dedicated_requirements = vku::InitStructHelper();
    VkMemoryRequirements2 buffer_memory_requirements = vku::InitStructHelper(&buffer_memory_dedicated_requirements);
    vk::GetBufferMemoryRequirements2(device(), &buffer_memory_requirements_info, &buffer_memory_requirements);

    VkImageMemoryRequirementsInfo2 image_memory_requirements_info = vku::InitStructHelper();
    image_memory_requirements_info.image = image;
    VkMemoryDedicatedRequirements image_memory_dedicated_requirements = vku::InitStructHelper();
    VkMemoryRequirements2 image_memory_requirements = vku::InitStructHelper(&image_memory_dedicated_requirements);
    vk::GetImageMemoryRequirements2(device(), &image_memory_requirements_info, &image_memory_requirements);

    VkDeviceSize memory_size =
        std::max(buffer_memory_requirements.memoryRequirements.size, image_memory_requirements.memoryRequirements.size);

    {
        VkMemoryDedicatedAllocateInfo memory_dedicated_allocate_info = vku::InitStructHelper();
        memory_dedicated_allocate_info.image = VK_NULL_HANDLE;
        memory_dedicated_allocate_info.buffer = buffer;
        VkMemoryAllocateInfo memory_info = vku::InitStructHelper(&memory_dedicated_allocate_info);
        memory_info.allocationSize = memory_size;
        bool pass = m_device->Physical().SetMemoryType(image_memory_requirements.memoryRequirements.memoryTypeBits, &memory_info,
                                                       VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
        ASSERT_TRUE(pass);
        vkt::DeviceMemory device_memory(*m_device, memory_info);
        m_errorMonitor->SetDesiredError("VUID-vkBindImageMemory-memory-10926");
        vk::BindImageMemory(device(), image, device_memory, 0u);
        m_errorMonitor->VerifyFound();
    }

    {
        VkMemoryDedicatedAllocateInfo memory_dedicated_allocate_info = vku::InitStructHelper();
        memory_dedicated_allocate_info.image = image;
        memory_dedicated_allocate_info.buffer = VK_NULL_HANDLE;
        VkMemoryAllocateInfo memory_info = vku::InitStructHelper(&memory_dedicated_allocate_info);
        memory_info.allocationSize = memory_size;
        bool pass = m_device->Physical().SetMemoryType(buffer_memory_requirements.memoryRequirements.memoryTypeBits, &memory_info,
                                                       VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
        ASSERT_TRUE(pass);
        vkt::DeviceMemory device_memory(*m_device, memory_info);
        m_errorMonitor->SetDesiredError("VUID-vkBindBufferMemory-memory-10925");
        vk::BindBufferMemory(device(), buffer, device_memory, 0u);
        m_errorMonitor->VerifyFound();
    }
}