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

#include "layer_validation_tests.h"

void ImageDrmTest::InitBasicImageDrm() {
    SetTargetApiVersion(VK_API_VERSION_1_2);  // required extension added here
    AddRequiredExtensions(VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::samplerYcbcrConversion);
    RETURN_IF_SKIP(Init());
}

std::vector<uint64_t> ImageDrmTest::GetFormatModifier(VkFormat format, VkFormatFeatureFlags2 features, uint32_t plane_count) {
    std::vector<uint64_t> mods;
    VkDrmFormatModifierPropertiesListEXT mod_props = vku::InitStructHelper();
    VkFormatProperties2 format_props = vku::InitStructHelper(&mod_props);
    vk::GetPhysicalDeviceFormatProperties2(Gpu(), format, &format_props);
    if (mod_props.drmFormatModifierCount == 0) {
        return mods;
    }

    std::vector<VkDrmFormatModifierPropertiesEXT> mod_props_length(mod_props.drmFormatModifierCount);
    mod_props.pDrmFormatModifierProperties = mod_props_length.data();
    vk::GetPhysicalDeviceFormatProperties2(Gpu(), format, &format_props);

    for (uint32_t i = 0; i < mod_props.drmFormatModifierCount; ++i) {
        auto& mod = mod_props.pDrmFormatModifierProperties[i];
        if (((mod.drmFormatModifierTilingFeatures & features) == features) && (plane_count == mod.drmFormatModifierPlaneCount)) {
            mods.push_back(mod.drmFormatModifier);
        }
    }

    return mods;
}

class PositiveImageDrm : public ImageDrmTest {};

TEST_F(PositiveImageDrm, Basic) {
    // See https://github.com/KhronosGroup/Vulkan-ValidationLayers/pull/2610
    // for more detailed checking, we could export the image to dmabuf
    // and then import it again (using VkImageDrmFormatModifierExplicitCreateInfoEXT)
    TEST_DESCRIPTION("Create image and imageView using VK_EXT_image_drm_format_modifier");
    RETURN_IF_SKIP(InitBasicImageDrm());

    // we just hope that one of these formats supports modifiers
    // for more detailed checking, we could also check multi-planar formats.
    auto format_list = {
        VK_FORMAT_B8G8R8A8_UNORM,
        VK_FORMAT_B8G8R8A8_SRGB,
        VK_FORMAT_R8G8B8A8_UNORM,
        VK_FORMAT_R8G8B8A8_SRGB,
    };

    for (auto format : format_list) {
        std::vector<uint64_t> mods =
            GetFormatModifier(format, VK_FORMAT_FEATURE_TRANSFER_DST_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
        if (mods.empty()) {
            continue;
        }

        // create image
        VkImageCreateInfo ci = vku::InitStructHelper();
        ci.flags = 0;
        ci.imageType = VK_IMAGE_TYPE_2D;
        ci.format = format;
        ci.extent = {128, 128, 1};
        ci.mipLevels = 1;
        ci.arrayLayers = 1;
        ci.samples = VK_SAMPLE_COUNT_1_BIT;
        ci.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
        ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
        ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
        ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;

        mods = GetSupportedDrmModifiers(Gpu(), mods, ci);
        if (mods.empty()) {
            continue;
        }

        VkImageDrmFormatModifierListCreateInfoEXT mod_list = vku::InitStructHelper();
        mod_list.pDrmFormatModifiers = mods.data();
        mod_list.drmFormatModifierCount = mods.size();
        ci.pNext = &mod_list;

        vkt::Image image(*m_device, ci, vkt::no_mem);

        VkMemoryRequirements mem_reqs = image.MemoryRequirements();
        VkMemoryAllocateInfo alloc_info = vku::InitStructHelper();
        alloc_info.allocationSize = mem_reqs.size;
        if (!m_device->Physical().SetMemoryType(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
            GTEST_SKIP() << "Memory type not found";
        }

        vkt::DeviceMemory memory(*m_device, alloc_info);
        ASSERT_EQ(VK_SUCCESS, vk::BindImageMemory(device(), image, memory, 0));
        vkt::ImageView image_view = image.CreateView();
    }
}

TEST_F(PositiveImageDrm, ExternalMemory) {
    // https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/5649
    TEST_DESCRIPTION(
        "Create image with VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT and VkExternalMemoryImageCreateInfo in the pNext chain");

    AddRequiredExtensions(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
    RETURN_IF_SKIP(InitBasicImageDrm());

    const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
    std::vector<uint64_t> mods = GetFormatModifier(format, VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
    if (mods.empty()) {
        GTEST_SKIP() << "No valid Format Modifier found";
    }

    VkExternalMemoryImageCreateInfo external_info = vku::InitStructHelper();
    external_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;

    VkImageCreateInfo ci = vku::InitStructHelper();
    ci.imageType = VK_IMAGE_TYPE_2D;
    ci.format = format;
    ci.extent = {128, 128, 1};
    ci.mipLevels = 1;
    ci.arrayLayers = 1;
    ci.samples = VK_SAMPLE_COUNT_1_BIT;
    ci.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
    ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
    ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;

    VkPhysicalDeviceExternalImageFormatInfo external_image_info = vku::InitStructHelper();
    external_image_info.handleType = static_cast<VkExternalMemoryHandleTypeFlagBits>(external_info.handleTypes);

    mods = GetSupportedDrmModifiers(Gpu(), mods, ci, &external_image_info);
    if (mods.empty()) {
        GTEST_SKIP() << "No valid Format Modifier found";
    }

    VkImageDrmFormatModifierListCreateInfoEXT drm_info = vku::InitStructHelper(&external_info);
    drm_info.drmFormatModifierCount = size32(mods);
    drm_info.pDrmFormatModifiers = mods.data();
    ci.pNext = &drm_info;

    {
        VkPhysicalDeviceImageDrmFormatModifierInfoEXT drm_format_modifier = vku::InitStructHelper();
        drm_format_modifier.drmFormatModifier = mods[0];
        drm_format_modifier.sharingMode = ci.sharingMode;
        drm_format_modifier.queueFamilyIndexCount = ci.queueFamilyIndexCount;
        drm_format_modifier.pQueueFamilyIndices = ci.pQueueFamilyIndices;
        external_image_info.pNext = &drm_format_modifier;
        VkPhysicalDeviceImageFormatInfo2 image_info = vku::InitStructHelper(&external_image_info);
        image_info.format = ci.format;
        image_info.type = ci.imageType;
        image_info.tiling = ci.tiling;
        image_info.usage = ci.usage;
        image_info.flags = ci.flags;

        VkExternalImageFormatProperties external_image_properties = vku::InitStructHelper();
        VkImageFormatProperties2 image_properties = vku::InitStructHelper(&external_image_properties);

        if (const auto result = vk::GetPhysicalDeviceImageFormatProperties2(Gpu(), &image_info, &image_properties);
            result != VK_SUCCESS) {
            GTEST_SKIP() << "Unable to create image. VkResult = " << string_VkResult(result);
        }

        if ((external_image_properties.externalMemoryProperties.compatibleHandleTypes & external_info.handleTypes) !=
            external_info.handleTypes) {
            GTEST_SKIP() << "Unable to create image, VkExternalMemoryImageCreateInfo::handleTypes not supported";
        }
    }
    vkt::Image image(*m_device, ci, vkt::no_mem);

    VkMemoryDedicatedAllocateInfo dedicated_info = vku::InitStructHelper();
    dedicated_info.image = image;
    VkMemoryAllocateInfo alloc_info = vku::InitStructHelper(&dedicated_info);
    VkMemoryRequirements mem_reqs = image.MemoryRequirements();
    alloc_info.allocationSize = mem_reqs.size;
    if (!m_device->Physical().SetMemoryType(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
        GTEST_SKIP() << "Memory type not found";
    }

    vkt::DeviceMemory memory(*m_device, alloc_info);
    ASSERT_EQ(VK_SUCCESS, vk::BindImageMemory(device(), image, memory, 0));
}

TEST_F(PositiveImageDrm, GetImageSubresourceLayoutPlane) {
    RETURN_IF_SKIP(InitBasicImageDrm());

    VkFormat format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
    std::vector<uint64_t> mods = GetFormatModifier(format, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, 2);
    if (mods.empty()) {
        GTEST_SKIP() << "No valid Format Modifier found";
    }

    VkImageCreateInfo create_info = vku::InitStructHelper();
    create_info.imageType = VK_IMAGE_TYPE_2D;
    create_info.format = format;
    create_info.extent = {64, 64, 1};
    create_info.mipLevels = 1;
    create_info.arrayLayers = 1;
    create_info.samples = VK_SAMPLE_COUNT_1_BIT;
    create_info.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
    create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;

    mods = GetSupportedDrmModifiers(Gpu(), mods, create_info);
    if (mods.empty()) {
        GTEST_SKIP() << "Required formats/features not supported";
    }

    VkImageDrmFormatModifierListCreateInfoEXT list_create_info = vku::InitStructHelper();
    list_create_info.drmFormatModifierCount = mods.size();
    list_create_info.pDrmFormatModifiers = mods.data();
    create_info.pNext = &list_create_info;

    vkt::Image image(*m_device, create_info, vkt::no_mem);
    if (image.initialized() == false) {
        GTEST_SKIP() << "Failed to create image.";
    }

    VkImageSubresource subresource{VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT, 0, 0};
    VkSubresourceLayout layout{};
    vk::GetImageSubresourceLayout(*m_device, image, &subresource, &layout);
}

TEST_F(PositiveImageDrm, MutableFormat) {
    TEST_DESCRIPTION("use VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT with no VkImageFormatListCreateInfo .");
    RETURN_IF_SKIP(InitBasicImageDrm());

    std::vector<uint64_t> mods = GetFormatModifier(VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
    if (mods.empty()) {
        GTEST_SKIP() << "No valid Format Modifier found";
    }

    VkFormat formats = VK_FORMAT_R8G8B8A8_SNORM;
    VkImageFormatListCreateInfo format_list = vku::InitStructHelper();
    format_list.viewFormatCount = 1;
    format_list.pViewFormats = &formats;

    VkImageCreateInfo image_info = vku::InitStructHelper();
    image_info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
    image_info.imageType = VK_IMAGE_TYPE_2D;
    image_info.format = VK_FORMAT_R8G8B8A8_UNORM;
    image_info.extent = {128, 128, 1};
    image_info.mipLevels = 1;
    image_info.arrayLayers = 1;
    image_info.samples = VK_SAMPLE_COUNT_1_BIT;
    image_info.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
    image_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
    image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
    image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;

    mods = GetSupportedDrmModifiers(Gpu(), mods, image_info, &format_list);
    if (mods.empty()) {
        GTEST_SKIP() << "No valid Format Modifier found";
    }

    VkImageDrmFormatModifierListCreateInfoEXT mod_list = vku::InitStructHelper();
    mod_list.pDrmFormatModifiers = mods.data();
    mod_list.drmFormatModifierCount = mods.size();
    format_list.pNext = &mod_list;
    image_info.pNext = &format_list;

    vkt::Image image(*m_device, image_info, vkt::no_mem);

    VkMemoryRequirements mem_reqs = image.MemoryRequirements();
    VkMemoryAllocateInfo alloc_info = vku::InitStructHelper();
    alloc_info.allocationSize = mem_reqs.size;
    if (!m_device->Physical().SetMemoryType(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
        GTEST_SKIP() << "Memory type not found";
    }

    vkt::DeviceMemory memory(*m_device, alloc_info);
    ASSERT_EQ(VK_SUCCESS, vk::BindImageMemory(device(), image, memory, 0));
}

TEST_F(PositiveImageDrm, MutableExternalMemory) {
    TEST_DESCRIPTION("https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/8627");
    AddRequiredExtensions(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
    RETURN_IF_SKIP(InitBasicImageDrm());

    const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
    std::vector<uint64_t> mods = GetFormatModifier(format, VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
    if (mods.empty()) {
        GTEST_SKIP() << "No valid Format Modifier found";
    }

    VkFormat formats = VK_FORMAT_R8G8B8A8_SNORM;
    VkImageFormatListCreateInfo format_list = vku::InitStructHelper();
    format_list.viewFormatCount = 1;
    format_list.pViewFormats = &formats;

    VkExternalMemoryImageCreateInfo external_info = vku::InitStructHelper(&format_list);
    external_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;

    VkImageCreateInfo ci = vku::InitStructHelper();
    ci.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
    ci.imageType = VK_IMAGE_TYPE_2D;
    ci.format = format;
    ci.extent = {128, 128, 1};
    ci.mipLevels = 1;
    ci.arrayLayers = 1;
    ci.samples = VK_SAMPLE_COUNT_1_BIT;
    ci.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
    ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
               VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
    ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
    ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;

    VkPhysicalDeviceExternalImageFormatInfo external_image_info = vku::InitStructHelper(&format_list);
    external_image_info.handleType = static_cast<VkExternalMemoryHandleTypeFlagBits>(external_info.handleTypes);

    mods = GetSupportedDrmModifiers(Gpu(), mods, ci, &external_image_info);
    if (mods.empty()) {
        GTEST_SKIP() << "No valid Format Modifier found";
    }

    VkImageDrmFormatModifierListCreateInfoEXT drm_info = vku::InitStructHelper(&external_info);
    drm_info.drmFormatModifierCount = size32(mods);
    drm_info.pDrmFormatModifiers = mods.data();
    ci.pNext = &drm_info;

    {
        VkPhysicalDeviceImageDrmFormatModifierInfoEXT drm_format_modifier = vku::InitStructHelper(&external_image_info);
        drm_format_modifier.drmFormatModifier = mods[0];
        drm_format_modifier.sharingMode = ci.sharingMode;
        drm_format_modifier.queueFamilyIndexCount = ci.queueFamilyIndexCount;
        drm_format_modifier.pQueueFamilyIndices = ci.pQueueFamilyIndices;
        VkPhysicalDeviceImageFormatInfo2 image_info = vku::InitStructHelper(&drm_format_modifier);
        image_info.format = ci.format;
        image_info.type = ci.imageType;
        image_info.tiling = ci.tiling;
        image_info.usage = ci.usage;
        image_info.flags = ci.flags;

        VkExternalImageFormatProperties external_image_properties = vku::InitStructHelper();
        VkImageFormatProperties2 image_properties = vku::InitStructHelper(&external_image_properties);

        if (const auto result = vk::GetPhysicalDeviceImageFormatProperties2(Gpu(), &image_info, &image_properties);
            result != VK_SUCCESS) {
            GTEST_SKIP() << "Unable to create image. VkResult = " << string_VkResult(result);
        }

        if ((external_image_properties.externalMemoryProperties.compatibleHandleTypes & external_info.handleTypes) !=
            external_info.handleTypes) {
            GTEST_SKIP() << "Unable to create image, VkExternalMemoryImageCreateInfo::handleTypes not supported";
        }
    }
    vkt::Image image(*m_device, ci, vkt::no_mem);

    VkMemoryDedicatedAllocateInfo dedicated_info = vku::InitStructHelper();
    dedicated_info.image = image;
    VkMemoryAllocateInfo alloc_info = vku::InitStructHelper(&dedicated_info);
    VkMemoryRequirements mem_reqs = image.MemoryRequirements();
    alloc_info.allocationSize = mem_reqs.size;
    if (!m_device->Physical().SetMemoryType(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
        GTEST_SKIP() << "Memory type not found";
    }

    vkt::DeviceMemory memory(*m_device, alloc_info);
    ASSERT_EQ(VK_SUCCESS, vk::BindImageMemory(device(), image, memory, 0));
}

TEST_F(PositiveImageDrm, GetImageDrmFormatModifierProperties) {
    TEST_DESCRIPTION("Use vkGetImageDrmFormatModifierPropertiesEXT");
    RETURN_IF_SKIP(InitBasicImageDrm());

    std::vector<uint64_t> mods = GetFormatModifier(VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
    if (mods.empty()) {
        GTEST_SKIP() << "No valid Format Modifier found";
    }

    VkImageCreateInfo image_info = vku::InitStructHelper();
    image_info.imageType = VK_IMAGE_TYPE_2D;
    image_info.format = VK_FORMAT_R8G8B8A8_UNORM;
    image_info.extent = {128, 128, 1};
    image_info.mipLevels = 1;
    image_info.arrayLayers = 1;
    image_info.samples = VK_SAMPLE_COUNT_1_BIT;
    image_info.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
    image_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
    image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
    image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;

    mods = GetSupportedDrmModifiers(Gpu(), mods, image_info);
    if (mods.empty()) {
        GTEST_SKIP() << "No valid Format Modifier found";
    }

    VkImageDrmFormatModifierListCreateInfoEXT mod_list = vku::InitStructHelper();
    mod_list.pDrmFormatModifiers = mods.data();
    mod_list.drmFormatModifierCount = mods.size();
    image_info.pNext = &mod_list;

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

    VkImageDrmFormatModifierPropertiesEXT props = vku::InitStructHelper();
    vk::GetImageDrmFormatModifierPropertiesEXT(device(), image, &props);
}

TEST_F(PositiveImageDrm, PhysicalDeviceImageDrmFormatModifierInfoExclusive) {
    TEST_DESCRIPTION("Use vkPhysicalDeviceImageDrmFormatModifierInfo with VK_SHARING_MODE_EXCLUSIVE");
    AddRequiredExtensions(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
    RETURN_IF_SKIP(InitBasicImageDrm());

    VkPhysicalDeviceImageDrmFormatModifierInfoEXT drm_format_modifier = vku::InitStructHelper();
    drm_format_modifier.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

    VkPhysicalDeviceExternalImageFormatInfo external_image_info = vku::InitStructHelper(&drm_format_modifier);
    external_image_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;

    VkPhysicalDeviceImageFormatInfo2 image_info = vku::InitStructHelper(&external_image_info);
    image_info.format = VK_FORMAT_R8G8B8A8_UNORM;
    image_info.type = VK_IMAGE_TYPE_2D;
    image_info.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
    image_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    image_info.flags = 0;

    VkExternalImageFormatProperties external_image_properties = vku::InitStructHelper();
    VkImageFormatProperties2 image_properties = vku::InitStructHelper(&external_image_properties);

    vk::GetPhysicalDeviceImageFormatProperties2(Gpu(), &image_info, &image_properties);
}

TEST_F(PositiveImageDrm, PhysicalDeviceImageDrmFormatModifierInfoConcurrent) {
    TEST_DESCRIPTION("Use vkPhysicalDeviceImageDrmFormatModifierInfo with VK_SHARING_MODE_CONCURRENT");
    AddRequiredExtensions(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
    RETURN_IF_SKIP(InitBasicImageDrm());

    uint32_t queue_family_property_count = 0;
    vk::GetPhysicalDeviceQueueFamilyProperties2(Gpu(), &queue_family_property_count, nullptr);
    if (queue_family_property_count < 2) {
        GTEST_SKIP() << "pQueueFamilyPropertyCount is not 2 or more";
    }
    std::vector<VkQueueFamilyProperties2> queue_family_props(queue_family_property_count);
    vk::GetPhysicalDeviceQueueFamilyProperties2(Gpu(), &queue_family_property_count, nullptr);

    VkPhysicalDeviceImageDrmFormatModifierInfoEXT drm_format_modifier = vku::InitStructHelper();
    drm_format_modifier.sharingMode = VK_SHARING_MODE_CONCURRENT;
    drm_format_modifier.queueFamilyIndexCount = 2;
    uint32_t queue_family_indices[2] = {0, 1};
    drm_format_modifier.pQueueFamilyIndices = queue_family_indices;

    VkPhysicalDeviceExternalImageFormatInfo external_image_info = vku::InitStructHelper(&drm_format_modifier);
    external_image_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;

    VkPhysicalDeviceImageFormatInfo2 image_info = vku::InitStructHelper(&external_image_info);
    image_info.format = VK_FORMAT_R8G8B8A8_UNORM;
    image_info.type = VK_IMAGE_TYPE_2D;
    image_info.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
    image_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    image_info.flags = 0;

    VkExternalImageFormatProperties external_image_properties = vku::InitStructHelper();
    VkImageFormatProperties2 image_properties = vku::InitStructHelper(&external_image_properties);

    vk::GetPhysicalDeviceImageFormatProperties2(Gpu(), &image_info, &image_properties);
}
