/*
 * 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) 2022 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 <gtest/gtest.h>
#include <vulkan/vulkan_core.h>
#include "utils/math_utils.h"
#include "../framework/layer_validation_tests.h"
#include "../framework/pipeline_helper.h"

class NegativeDeviceAddress : public VkLayerTest {};

TEST_F(NegativeDeviceAddress, DestroyOnlyBuffer) {
    AddRequiredExtensions(VK_KHR_COPY_MEMORY_INDIRECT_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::indirectMemoryCopy);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());

    const size_t copy_size = sizeof(VkCopyMemoryIndirectCommandKHR);
    vkt::Buffer indirect_buffer(*m_device, copy_size, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, vkt::device_address);

    VkStridedDeviceAddressRangeKHR copy_address_range = {};
    copy_address_range.address = indirect_buffer.Address();
    copy_address_range.stride = copy_size;
    copy_address_range.size = copy_size;

    VkCopyMemoryIndirectInfoKHR indirect_info = vku::InitStructHelper();
    indirect_info.copyCount = 1u;
    indirect_info.copyAddressRange = copy_address_range;

    m_command_buffer.Begin();
    vk::CmdCopyMemoryIndirectKHR(m_command_buffer, &indirect_info);
    m_command_buffer.End();

    indirect_buffer.Destroy();
    m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-00070");
    m_default_queue->SubmitAndWait(m_command_buffer);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDeviceAddress, DestroyAllBuffers) {
    AddRequiredExtensions(VK_KHR_COPY_MEMORY_INDIRECT_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::indirectMemoryCopy);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());

    const size_t copy_size = sizeof(VkCopyMemoryIndirectCommandKHR);
    VkBufferCreateInfo buffer_ci = vku::InitStructHelper();
    buffer_ci.size = copy_size;
    buffer_ci.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
    vkt::Buffer indirect_buffer1(*m_device, buffer_ci, vkt::no_mem);
    vkt::Buffer indirect_buffer2(*m_device, buffer_ci, vkt::no_mem);

    VkMemoryRequirements memory_requirements;
    vk::GetBufferMemoryRequirements(*m_device, indirect_buffer1, &memory_requirements);

    VkMemoryAllocateFlagsInfo memory_allocate_flags = vku::InitStructHelper();
    memory_allocate_flags.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT;
    VkMemoryAllocateInfo memory_ai = vku::InitStructHelper(&memory_allocate_flags);
    memory_ai.allocationSize = memory_requirements.size;

    bool pass =
        m_device->Physical().SetMemoryType(memory_requirements.memoryTypeBits, &memory_ai, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
    ASSERT_TRUE(pass);
    vkt::DeviceMemory memory(*m_device, memory_ai);

    vk::BindBufferMemory(*m_device, indirect_buffer1, memory, 0);
    vk::BindBufferMemory(*m_device, indirect_buffer2, memory, 0);

    VkDeviceAddress address1 = indirect_buffer1.Address();
    VkDeviceAddress address2 = indirect_buffer2.Address();

    if (address1 != address2) {
        GTEST_SKIP() << "Device addresses are not equal.";
    }

    VkStridedDeviceAddressRangeKHR copy_address_range = {};
    copy_address_range.address = indirect_buffer1.Address();
    copy_address_range.stride = copy_size;
    copy_address_range.size = copy_size;

    VkCopyMemoryIndirectInfoKHR indirect_info = vku::InitStructHelper();
    indirect_info.copyCount = 1u;
    indirect_info.copyAddressRange = copy_address_range;

    m_command_buffer.Begin();
    vk::CmdCopyMemoryIndirectKHR(m_command_buffer, &indirect_info);
    m_command_buffer.End();

    indirect_buffer1.Destroy();
    indirect_buffer2.Destroy();
    m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-00070");
    m_default_queue->SubmitAndWait(m_command_buffer);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDeviceAddress, GetSecondDeviceAddressAfterInvalidation) {
    AddRequiredExtensions(VK_KHR_COPY_MEMORY_INDIRECT_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::indirectMemoryCopy);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());

    const size_t copy_size = sizeof(VkCopyMemoryIndirectCommandKHR);
    VkBufferCreateInfo buffer_ci = vku::InitStructHelper();
    buffer_ci.size = copy_size;
    buffer_ci.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
    vkt::Buffer indirect_buffer1(*m_device, buffer_ci, vkt::no_mem);
    vkt::Buffer indirect_buffer2(*m_device, buffer_ci, vkt::no_mem);

    VkMemoryRequirements memory_requirements;
    vk::GetBufferMemoryRequirements(*m_device, indirect_buffer1, &memory_requirements);

    VkMemoryAllocateFlagsInfo memory_allocate_flags = vku::InitStructHelper();
    memory_allocate_flags.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT;
    VkMemoryAllocateInfo memory_ai = vku::InitStructHelper(&memory_allocate_flags);
    memory_ai.allocationSize = memory_requirements.size;

    bool pass =
        m_device->Physical().SetMemoryType(memory_requirements.memoryTypeBits, &memory_ai, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
    ASSERT_TRUE(pass);
    vkt::DeviceMemory memory(*m_device, memory_ai);

    vk::BindBufferMemory(*m_device, indirect_buffer1, memory, 0);
    vk::BindBufferMemory(*m_device, indirect_buffer2, memory, 0);

    VkDeviceAddress address1 = indirect_buffer1.Address();

    VkStridedDeviceAddressRangeKHR copy_address_range = {};
    copy_address_range.address = indirect_buffer1.Address();
    copy_address_range.stride = copy_size;
    copy_address_range.size = copy_size;

    VkCopyMemoryIndirectInfoKHR indirect_info = vku::InitStructHelper();
    indirect_info.copyCount = 1u;
    indirect_info.copyAddressRange = copy_address_range;

    m_command_buffer.Begin();
    vk::CmdCopyMemoryIndirectKHR(m_command_buffer, &indirect_info);
    m_command_buffer.End();

    indirect_buffer1.Destroy();
    VkDeviceAddress address2 = indirect_buffer2.Address();

    if (address1 != address2) {
        GTEST_SKIP() << "Device addresses are not equal.";
    }

    m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-00070");
    m_default_queue->SubmitAndWait(m_command_buffer);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDeviceAddress, SecondBufferUnrelatedUsage) {
    AddRequiredExtensions(VK_KHR_COPY_MEMORY_INDIRECT_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::indirectMemoryCopy);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());

    const size_t copy_size = sizeof(VkCopyMemoryIndirectCommandKHR);
    VkBufferCreateInfo buffer_ci = vku::InitStructHelper();
    buffer_ci.size = copy_size;
    buffer_ci.usage = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
    vkt::Buffer indirect_buffer1(*m_device, buffer_ci, vkt::no_mem);
    buffer_ci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
    vkt::Buffer indirect_buffer2(*m_device, buffer_ci, vkt::no_mem);

    VkMemoryRequirements memory_requirements;
    vk::GetBufferMemoryRequirements(*m_device, indirect_buffer1, &memory_requirements);

    VkMemoryAllocateFlagsInfo memory_allocate_flags = vku::InitStructHelper();
    memory_allocate_flags.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT;
    VkMemoryAllocateInfo memory_ai = vku::InitStructHelper(&memory_allocate_flags);
    memory_ai.allocationSize = memory_requirements.size;

    bool pass =
        m_device->Physical().SetMemoryType(memory_requirements.memoryTypeBits, &memory_ai, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
    ASSERT_TRUE(pass);
    vkt::DeviceMemory memory(*m_device, memory_ai);

    vk::BindBufferMemory(*m_device, indirect_buffer1, memory, 0);
    vk::BindBufferMemory(*m_device, indirect_buffer2, memory, 0);

    VkDeviceAddress address1 = indirect_buffer1.Address();
    VkDeviceAddress address2 = indirect_buffer2.Address();

    if (address1 != address2) {
        GTEST_SKIP() << "Device addresses are not equal.";
    }

    VkStridedDeviceAddressRangeKHR copy_address_range = {};
    copy_address_range.address = indirect_buffer1.Address();
    copy_address_range.stride = copy_size;
    copy_address_range.size = copy_size;

    VkCopyMemoryIndirectInfoKHR indirect_info = vku::InitStructHelper();
    indirect_info.copyCount = 1u;
    indirect_info.copyAddressRange = copy_address_range;

    m_command_buffer.Begin();
    vk::CmdCopyMemoryIndirectKHR(m_command_buffer, &indirect_info);
    m_command_buffer.End();

    indirect_buffer1.Destroy();
    m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-00070");
    m_default_queue->SubmitAndWait(m_command_buffer);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDeviceAddress, DestroyBeforeCmdBufferEnd) {
    AddRequiredExtensions(VK_KHR_COPY_MEMORY_INDIRECT_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::indirectMemoryCopy);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());

    const size_t copy_size = sizeof(VkCopyMemoryIndirectCommandKHR);
    vkt::Buffer indirect_buffer(*m_device, copy_size, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, vkt::device_address);

    VkStridedDeviceAddressRangeKHR copy_address_range = {};
    copy_address_range.address = indirect_buffer.Address();
    copy_address_range.stride = copy_size;
    copy_address_range.size = copy_size;

    VkCopyMemoryIndirectInfoKHR indirect_info = vku::InitStructHelper();
    indirect_info.copyCount = 1u;
    indirect_info.copyAddressRange = copy_address_range;

    m_command_buffer.Begin();
    vk::CmdCopyMemoryIndirectKHR(m_command_buffer, &indirect_info);
    indirect_buffer.Destroy();
    m_errorMonitor->SetDesiredError("VUID-vkEndCommandBuffer-commandBuffer-00059");
    vk::EndCommandBuffer(m_command_buffer);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDeviceAddress, MemoryToImageIndirect) {
    AddRequiredExtensions(VK_KHR_COPY_MEMORY_INDIRECT_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::indirectMemoryToImageCopy);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());

    VkCopyMemoryToImageIndirectCommandKHR cmd1 = {};
    cmd1.srcAddress = 0;
    cmd1.bufferRowLength = 8;
    cmd1.bufferImageHeight = 8;
    cmd1.imageSubresource = {};
    cmd1.imageOffset = {0, 0, 0};
    cmd1.imageExtent = {8, 8, 1};

    VkCopyMemoryToImageIndirectCommandKHR cmd2 = {};
    cmd2.srcAddress = 1024;
    cmd2.bufferRowLength = 4;
    cmd2.bufferImageHeight = 4;
    cmd2.imageSubresource = {};
    cmd2.imageOffset = {0, 0, 0};
    cmd2.imageExtent = {4, 4, 1};

    VkCopyMemoryToImageIndirectCommandKHR cmds[2] = {cmd1, cmd2};

    vkt::Buffer indirect_buffer(*m_device, sizeof(cmds), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, vkt::device_address);

    VkImageSubresourceLayers res_layer = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
    VkImageSubresourceLayers res_layers[2] = {res_layer, res_layer};

    m_command_buffer.Begin();

    VkImageCreateInfo image_create_info = vku::InitStructHelper();
    image_create_info.imageType = VK_IMAGE_TYPE_2D;
    image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
    image_create_info.extent = {32, 32, 1};
    image_create_info.mipLevels = 1;
    image_create_info.arrayLayers = 4;
    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.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    image_create_info.flags = 0;
    vkt::Image src_image(*m_device, image_create_info, vkt::set_layout);

    image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
    vkt::Image dst_image(*m_device, image_create_info, vkt::set_layout);

    VkImageCopy copy_region;
    copy_region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
    copy_region.dstSubresource = copy_region.srcSubresource;
    copy_region.srcOffset = {0, 0, 0};
    copy_region.dstOffset = {0, 0, 0};
    copy_region.extent = {1, 1, 1};

    const uint32_t stride = sizeof(VkCopyMemoryToImageIndirectCommandKHR);

    VkStridedDeviceAddressRangeKHR address_range = {};
    address_range.address = indirect_buffer.Address();
    address_range.size = sizeof(cmds);
    address_range.stride = stride;

    VkCopyMemoryToImageIndirectInfoKHR copy_info = vku::InitStructHelper();
    copy_info.copyCount = 2;
    copy_info.copyAddressRange = address_range;
    copy_info.srcCopyFlags = VK_ADDRESS_COPY_DEVICE_LOCAL_BIT_KHR;
    copy_info.dstImage = dst_image;
    copy_info.dstImageLayout = VK_IMAGE_LAYOUT_GENERAL;
    copy_info.pImageSubresources = res_layers;

    vk::CmdCopyImage(m_command_buffer, src_image, VK_IMAGE_LAYOUT_GENERAL, dst_image, VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
    vk::CmdCopyMemoryToImageIndirectKHR(m_command_buffer, &copy_info);
    m_command_buffer.End();

    indirect_buffer.Destroy();
    m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-00070");
    m_default_queue->SubmitAndWait(m_command_buffer);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDeviceAddress, MultipleBrokenRanges) {
    AddRequiredExtensions(VK_KHR_COPY_MEMORY_INDIRECT_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::indirectMemoryToImageCopy);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    RETURN_IF_SKIP(Init());

    VkCopyMemoryToImageIndirectCommandKHR cmd1 = {};
    cmd1.srcAddress = 0;
    cmd1.bufferRowLength = 8;
    cmd1.bufferImageHeight = 8;
    cmd1.imageSubresource = {};
    cmd1.imageOffset = {0, 0, 0};
    cmd1.imageExtent = {8, 8, 1};

    vkt::Buffer indirect_buffer1(*m_device, sizeof(cmd1), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, vkt::device_address);
    vkt::Buffer indirect_buffer2(*m_device, sizeof(cmd1) * 2,
                                 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, vkt::device_address);

    const VkDeviceAddress address1 = indirect_buffer1.Address();
    const VkDeviceAddress address2 = indirect_buffer2.Address();
    if (address1 == address2) {
        GTEST_SKIP() << "Device addresses areequal.";
    }

    m_command_buffer.Begin();

    vkt::Image dst_image(*m_device, 32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT);

    VkStridedDeviceAddressRangeKHR address_range = {};
    address_range.address = address1;
    address_range.size = sizeof(cmd1);
    address_range.stride = sizeof(VkCopyMemoryToImageIndirectCommandKHR);

    VkImageSubresourceLayers res_layer = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
    VkCopyMemoryToImageIndirectInfoKHR copy_info = vku::InitStructHelper();
    copy_info.copyCount = 1;
    copy_info.copyAddressRange = address_range;
    copy_info.srcCopyFlags = VK_ADDRESS_COPY_DEVICE_LOCAL_BIT_KHR;
    copy_info.dstImage = dst_image;
    copy_info.dstImageLayout = VK_IMAGE_LAYOUT_GENERAL;
    copy_info.pImageSubresources = &res_layer;

    vk::CmdCopyMemoryToImageIndirectKHR(m_command_buffer, &copy_info);

    copy_info.copyAddressRange.address = address2;
    vk::CmdCopyMemoryToImageIndirectKHR(m_command_buffer, &copy_info);

    indirect_buffer1.Destroy();
    indirect_buffer2.Destroy();
    m_errorMonitor->SetDesiredError("VUID-vkEndCommandBuffer-commandBuffer-00059");
    vk::EndCommandBuffer(m_command_buffer);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDeviceAddress, BindResourceHeap) {
    SetTargetApiVersion(VK_API_VERSION_1_3);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_DESCRIPTOR_HEAP_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    AddRequiredFeature(vkt::Feature::descriptorHeap);
    RETURN_IF_SKIP(Init());

    VkPhysicalDeviceDescriptorHeapPropertiesEXT heap_props = vku::InitStructHelper();
    VkPhysicalDeviceProperties2 props2 = vku::InitStructHelper(&heap_props);
    GetPhysicalDeviceProperties2(props2);

    const VkDeviceSize resource_stride = std::max(heap_props.resourceHeapAlignment, heap_props.imageDescriptorAlignment);

    const VkDeviceSize heap_size =
        Align(Align(resource_stride + heap_props.minResourceHeapReservedRange, heap_props.bufferDescriptorAlignment),
              heap_props.imageDescriptorAlignment);

    VkBufferUsageFlags2CreateInfo buffer_usage = vku::InitStructHelper();
    buffer_usage.usage = VK_BUFFER_USAGE_2_DESCRIPTOR_HEAP_BIT_EXT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT;
    VkMemoryAllocateFlagsInfo allocate_flag_info = vku::InitStructHelper();
    allocate_flag_info.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT;

    vkt::Buffer resource_heap(*m_device, vkt::Buffer::CreateInfo(heap_size, 0, {}, &buffer_usage),
                              VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &allocate_flag_info);

    VkBindHeapInfoEXT bind_info = vku::InitStructHelper();
    bind_info.heapRange = resource_heap.AddressRange();
    bind_info.reservedRangeOffset = 0;
    bind_info.reservedRangeSize = heap_props.minResourceHeapReservedRange;

    m_command_buffer.Begin();
    vk::CmdBindResourceHeapEXT(m_command_buffer, &bind_info);
    m_command_buffer.End();

    resource_heap.Destroy();

    m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-00070");
    m_default_queue->SubmitAndWait(m_command_buffer);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDeviceAddress, BindSamplerHeap) {
    SetTargetApiVersion(VK_API_VERSION_1_3);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_DESCRIPTOR_HEAP_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    AddRequiredFeature(vkt::Feature::descriptorHeap);
    RETURN_IF_SKIP(Init());

    VkPhysicalDeviceDescriptorHeapPropertiesEXT heap_props = vku::InitStructHelper();
    VkPhysicalDeviceProperties2 props2 = vku::InitStructHelper(&heap_props);
    GetPhysicalDeviceProperties2(props2);

    const VkDeviceSize sampler_stride = std::max(heap_props.samplerHeapAlignment, heap_props.samplerDescriptorAlignment);
    const VkDeviceSize heap_size =
        Align(sampler_stride + heap_props.minSamplerHeapReservedRange, heap_props.samplerDescriptorAlignment);

    VkBufferUsageFlags2CreateInfo buffer_usage = vku::InitStructHelper();
    buffer_usage.usage = VK_BUFFER_USAGE_2_DESCRIPTOR_HEAP_BIT_EXT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT;
    VkMemoryAllocateFlagsInfo allocate_flag_info = vku::InitStructHelper();
    allocate_flag_info.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT;

    vkt::Buffer sampler_heap(*m_device, vkt::Buffer::CreateInfo(heap_size, 0, {}, &buffer_usage),
                             VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &allocate_flag_info);

    VkBindHeapInfoEXT bind_info = vku::InitStructHelper();
    bind_info.heapRange = sampler_heap.AddressRange();
    bind_info.reservedRangeOffset = 0;
    bind_info.reservedRangeSize = heap_props.minSamplerHeapReservedRange;

    m_command_buffer.Begin();
    vk::CmdBindSamplerHeapEXT(m_command_buffer, &bind_info);
    m_command_buffer.End();

    sampler_heap.Destroy();

    m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-00070");
    m_default_queue->SubmitAndWait(m_command_buffer);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDeviceAddress, PartialValidRange) {
    SetTargetApiVersion(VK_API_VERSION_1_3);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_DESCRIPTOR_HEAP_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    AddRequiredFeature(vkt::Feature::descriptorHeap);
    RETURN_IF_SKIP(Init());

    VkPhysicalDeviceDescriptorHeapPropertiesEXT heap_props = vku::InitStructHelper();
    VkPhysicalDeviceProperties2 props2 = vku::InitStructHelper(&heap_props);
    GetPhysicalDeviceProperties2(props2);

    const VkDeviceSize heap_size = heap_props.minSamplerHeapReservedRange + 256;
    const VkDeviceSize offset = heap_size / 2;

    VkBufferUsageFlags2CreateInfo buffer_usage = vku::InitStructHelper();
    buffer_usage.usage = VK_BUFFER_USAGE_2_DESCRIPTOR_HEAP_BIT_EXT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT;
    VkBufferCreateInfo buffer_ci = vku::InitStructHelper(&buffer_usage);
    buffer_ci.size = heap_size;
    vkt::Buffer heap1(*m_device, buffer_ci, vkt::no_mem);
    buffer_ci.size = heap_size - offset;
    vkt::Buffer heap2(*m_device, buffer_ci, vkt::no_mem);

    VkMemoryRequirements memory_requirements;
    vk::GetBufferMemoryRequirements(*m_device, heap1, &memory_requirements);

    VkMemoryAllocateFlagsInfo memory_allocate_flags = vku::InitStructHelper();
    memory_allocate_flags.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT;
    VkMemoryAllocateInfo memory_ai = vku::InitStructHelper(&memory_allocate_flags);
    // make large enough if offset is not perfectly in the middle of the allocation
    memory_ai.allocationSize = memory_requirements.size * 2;

    bool pass =
        m_device->Physical().SetMemoryType(memory_requirements.memoryTypeBits, &memory_ai, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
    ASSERT_TRUE(pass);
    vkt::DeviceMemory memory(*m_device, memory_ai);

    vk::BindBufferMemory(*m_device, heap1, memory, 0);
    vk::BindBufferMemory(*m_device, heap2, memory, offset);

    VkDeviceAddress address1 = heap1.Address();
    VkDeviceAddress address2 = heap2.Address();
    (void)address2;

    VkBindHeapInfoEXT bind_info = vku::InitStructHelper();
    bind_info.heapRange = {address1, heap_size};
    bind_info.reservedRangeOffset = 0;
    bind_info.reservedRangeSize = heap_props.minSamplerHeapReservedRange;

    m_command_buffer.Begin();
    vk::CmdBindSamplerHeapEXT(m_command_buffer, &bind_info);
    m_command_buffer.End();

    heap1.Destroy();

    m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-00070");
    m_default_queue->SubmitAndWait(m_command_buffer);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDeviceAddress, ValidRangeTooSmall) {
    SetTargetApiVersion(VK_API_VERSION_1_3);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_DESCRIPTOR_HEAP_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    AddRequiredFeature(vkt::Feature::descriptorHeap);
    RETURN_IF_SKIP(Init());

    VkPhysicalDeviceDescriptorHeapPropertiesEXT heap_props = vku::InitStructHelper();
    VkPhysicalDeviceProperties2 props2 = vku::InitStructHelper(&heap_props);
    GetPhysicalDeviceProperties2(props2);

    const VkDeviceSize heap_size = heap_props.minSamplerHeapReservedRange + 256;
    const VkDeviceSize offset = heap_size / 2;

    VkBufferUsageFlags2CreateInfo buffer_usage = vku::InitStructHelper();
    buffer_usage.usage = VK_BUFFER_USAGE_2_DESCRIPTOR_HEAP_BIT_EXT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT;
    VkBufferCreateInfo buffer_ci = vku::InitStructHelper(&buffer_usage);
    buffer_ci.size = heap_size;
    vkt::Buffer heap1(*m_device, buffer_ci, vkt::no_mem);
    buffer_ci.size = heap_size - offset;
    vkt::Buffer heap2(*m_device, buffer_ci, vkt::no_mem);

    VkMemoryRequirements memory_requirements;
    vk::GetBufferMemoryRequirements(*m_device, heap1, &memory_requirements);

    VkMemoryAllocateFlagsInfo memory_allocate_flags = vku::InitStructHelper();
    memory_allocate_flags.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT;
    VkMemoryAllocateInfo memory_ai = vku::InitStructHelper(&memory_allocate_flags);
    memory_ai.allocationSize = memory_requirements.size;

    bool pass =
        m_device->Physical().SetMemoryType(memory_requirements.memoryTypeBits, &memory_ai, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
    ASSERT_TRUE(pass);
    vkt::DeviceMemory memory(*m_device, memory_ai);

    vk::BindBufferMemory(*m_device, heap1, memory, 0);
    vk::BindBufferMemory(*m_device, heap2, memory, 0);

    VkDeviceAddress address1 = heap1.Address();
    VkDeviceAddress address2 = heap2.Address();
    (void)address2;

    VkBindHeapInfoEXT bind_info = vku::InitStructHelper();
    bind_info.heapRange = {address1, heap_size};
    bind_info.reservedRangeOffset = 0;
    bind_info.reservedRangeSize = heap_props.minSamplerHeapReservedRange;

    m_command_buffer.Begin();
    vk::CmdBindSamplerHeapEXT(m_command_buffer, &bind_info);
    m_command_buffer.End();

    heap1.Destroy();

    m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-00070");
    m_default_queue->SubmitAndWait(m_command_buffer);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDeviceAddress, RangeSplitBetweenBuffers) {
    SetTargetApiVersion(VK_API_VERSION_1_3);
    AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_DESCRIPTOR_HEAP_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    AddRequiredFeature(vkt::Feature::descriptorHeap);
    RETURN_IF_SKIP(Init());

    VkPhysicalDeviceDescriptorHeapPropertiesEXT heap_props = vku::InitStructHelper();
    VkPhysicalDeviceProperties2 props2 = vku::InitStructHelper(&heap_props);
    GetPhysicalDeviceProperties2(props2);

    const VkDeviceSize heap_size = heap_props.minSamplerHeapReservedRange + 256;
    const VkDeviceSize offset = heap_size / 2;

    VkBufferUsageFlags2CreateInfo buffer_usage = vku::InitStructHelper();
    buffer_usage.usage = VK_BUFFER_USAGE_2_DESCRIPTOR_HEAP_BIT_EXT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT;
    VkBufferCreateInfo buffer_ci = vku::InitStructHelper(&buffer_usage);
    buffer_ci.size = heap_size;
    vkt::Buffer heap1(*m_device, buffer_ci, vkt::no_mem);
    buffer_ci.size = heap_size - offset;
    vkt::Buffer heap2(*m_device, buffer_ci, vkt::no_mem);
    vkt::Buffer heap3(*m_device, buffer_ci, vkt::no_mem);

    VkMemoryRequirements memory_requirements;
    vk::GetBufferMemoryRequirements(*m_device, heap1, &memory_requirements);

    VkMemoryAllocateFlagsInfo memory_allocate_flags = vku::InitStructHelper();
    memory_allocate_flags.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT;
    VkMemoryAllocateInfo memory_ai = vku::InitStructHelper(&memory_allocate_flags);
    // make large enough if offset is not perfectly in the middle of the allocation
    memory_ai.allocationSize = memory_requirements.size * 2;

    bool pass =
        m_device->Physical().SetMemoryType(memory_requirements.memoryTypeBits, &memory_ai, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
    ASSERT_TRUE(pass);
    vkt::DeviceMemory memory(*m_device, memory_ai);

    vk::BindBufferMemory(*m_device, heap1, memory, 0);
    vk::BindBufferMemory(*m_device, heap2, memory, 0);
    vk::BindBufferMemory(*m_device, heap3, memory, offset);

    VkDeviceAddress address1 = heap1.Address();
    VkDeviceAddress address2 = heap2.Address();
    VkDeviceAddress address3 = heap2.Address();
    (void)address2;
    (void)address3;

    VkBindHeapInfoEXT bind_info = vku::InitStructHelper();
    bind_info.heapRange = {address1, heap_size};
    bind_info.reservedRangeOffset = 0;
    bind_info.reservedRangeSize = heap_props.minSamplerHeapReservedRange;

    m_command_buffer.Begin();
    vk::CmdBindSamplerHeapEXT(m_command_buffer, &bind_info);
    m_command_buffer.End();

    heap1.Destroy();
    m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-00070");
    m_default_queue->SubmitAndWait(m_command_buffer);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDeviceAddress, IndexBuffer) {
    SetTargetApiVersion(VK_API_VERSION_1_3);
    AddRequiredExtensions(VK_KHR_DEVICE_ADDRESS_COMMANDS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    AddRequiredFeature(vkt::Feature::deviceAddressCommands);
    RETURN_IF_SKIP(Init());

    vkt::Buffer buffer(*m_device, 256u, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, vkt::device_address);

    VkBindIndexBuffer3InfoKHR info = vku::InitStructHelper();
    info.addressRange = buffer.AddressRange();
    info.addressFlags = 0u;
    info.indexType = VK_INDEX_TYPE_UINT32;

    m_command_buffer.Begin();
    vk::CmdBindIndexBuffer3KHR(m_command_buffer, &info);
    m_command_buffer.End();

    buffer.Destroy();
    m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-00070");
    m_default_queue->SubmitAndWait(m_command_buffer);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDeviceAddress, CmdDrawIndirect2KHR) {
    SetTargetApiVersion(VK_API_VERSION_1_3);
    AddRequiredExtensions(VK_KHR_DEVICE_ADDRESS_COMMANDS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    AddRequiredFeature(vkt::Feature::deviceAddressCommands);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    CreatePipelineHelper pipe(*this);
    pipe.CreateGraphicsPipeline();

    vkt::Buffer buffer(*m_device, sizeof(VkDrawIndirectCommand), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, vkt::device_address);
    VkDrawIndirectCommand* draw_ptr = static_cast<VkDrawIndirectCommand*>(buffer.Memory().Map());
    draw_ptr->vertexCount = 3u;
    draw_ptr->instanceCount = 1u;
    draw_ptr->firstVertex = 0u;
    draw_ptr->firstInstance = 0u;

    VkDrawIndirect2InfoKHR info = vku::InitStructHelper();
    info.addressRange = buffer.StridedAddressRange(sizeof(VkDrawIndirectCommand));
    info.addressFlags = 0u;
    info.drawCount = 1u;

    m_command_buffer.Begin();
    m_command_buffer.BeginRenderPass(m_renderPassBeginInfo);
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
    vk::CmdDrawIndirect2KHR(m_command_buffer, &info);
    m_command_buffer.EndRenderPass();
    m_command_buffer.End();

    buffer.Destroy();
    m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-00070");
    m_default_queue->SubmitAndWait(m_command_buffer);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDeviceAddress, CmdFillMemoryUsage) {
    SetTargetApiVersion(VK_API_VERSION_1_3);
    AddRequiredExtensions(VK_KHR_DEVICE_ADDRESS_COMMANDS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    AddRequiredFeature(vkt::Feature::deviceAddressCommands);
    RETURN_IF_SKIP(Init());

    vkt::Buffer buffer(*m_device, 256u, VK_BUFFER_USAGE_TRANSFER_DST_BIT, vkt::device_address);

    VkDeviceAddressRangeKHR range;
    range.address = buffer.Address();
    range.size = 256u;
    const uint32_t data = 255;

    VkAddressCommandFlagsKHR flags = 0u;

    m_command_buffer.Begin();
    vk::CmdFillMemoryKHR(m_command_buffer, &range, flags, data);
    m_command_buffer.End();

    buffer.Destroy();
    m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-00070");
    m_default_queue->SubmitAndWait(m_command_buffer);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDeviceAddress, ConditionalRendering) {
    SetTargetApiVersion(VK_API_VERSION_1_3);
    AddRequiredExtensions(VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME);
    AddRequiredExtensions(VK_KHR_DEVICE_ADDRESS_COMMANDS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::conditionalRendering);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    AddRequiredFeature(vkt::Feature::deviceAddressCommands);
    RETURN_IF_SKIP(Init());

    vkt::Buffer buffer(*m_device, 256u, VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT, vkt::device_address);

    VkConditionalRenderingBeginInfo2EXT info = vku::InitStructHelper();
    info.addressRange = buffer.AddressRange();
    info.addressFlags = 0u;
    info.flags = 0u;

    m_command_buffer.Begin();
    vk::CmdBeginConditionalRendering2EXT(m_command_buffer, &info);
    vk::CmdEndConditionalRenderingEXT(m_command_buffer);
    m_command_buffer.End();

    buffer.Destroy();
    m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-00070");
    m_default_queue->SubmitAndWait(m_command_buffer);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeDeviceAddress, TransformFeedback) {
    SetTargetApiVersion(VK_API_VERSION_1_3);
    AddRequiredExtensions(VK_KHR_DEVICE_ADDRESS_COMMANDS_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::bufferDeviceAddress);
    AddRequiredFeature(vkt::Feature::deviceAddressCommands);
    AddRequiredFeature(vkt::Feature::transformFeedback);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    CreatePipelineHelper pipe(*this);
    pipe.CreateGraphicsPipeline();

    vkt::Buffer buffer(
        *m_device, 256u,
        VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT,
        vkt::device_address);
    VkBindTransformFeedbackBuffer2InfoEXT info = vku::InitStructHelper();
    info.addressRange = buffer.AddressRange();
    info.addressFlags = VK_ADDRESS_COMMAND_TRANSFORM_FEEDBACK_BUFFER_USAGE_BIT_KHR;

    m_command_buffer.Begin();
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
    m_command_buffer.BeginRenderPass(m_renderPassBeginInfo);

    vk::CmdBindTransformFeedbackBuffers2EXT(m_command_buffer, 0u, 1u, &info);

    m_command_buffer.EndRenderPass();
    m_command_buffer.End();

    buffer.Destroy();
    m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-00070");
    m_default_queue->SubmitAndWait(m_command_buffer);
    m_errorMonitor->VerifyFound();
}
