/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * 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
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "Vulkan.h"

#include <iostream>
#include <string>
#include <unordered_set>
#include <vector>

VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE

namespace gfxstream {
namespace {

constexpr const bool kEnableValidationLayers = false;

static VKAPI_ATTR VkBool32 VKAPI_CALL VulkanDebugCallback(
        VkDebugUtilsMessageSeverityFlagBitsEXT severity,
        VkDebugUtilsMessageTypeFlagsEXT,
        const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
        void*) {
    if (severity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) {
        std::cout << pCallbackData->pMessage << std::endl;
    } else if (severity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) {
        std::cout << pCallbackData->pMessage << std::endl;
    } else if (severity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
        std::cout << pCallbackData->pMessage << std::endl;
    } else if (severity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
        std::cout << pCallbackData->pMessage << std::endl;
    }
    return VK_FALSE;
}

uint32_t GetMemoryType(const vkhpp::PhysicalDevice& physical_device,
                       uint32_t memory_type_mask,
                       vkhpp::MemoryPropertyFlags memoryProperties) {
    const auto props = physical_device.getMemoryProperties();
    for (uint32_t i = 0; i < props.memoryTypeCount; i++) {
        if (!(memory_type_mask & (1 << i))) {
            continue;
        }
        if ((props.memoryTypes[i].propertyFlags & memoryProperties) != memoryProperties) {
            continue;
        }
        return i;
    }
    return -1;
}

}  // namespace

gfxstream::expected<Vk::BufferWithMemory, vkhpp::Result> DoCreateBuffer(
        const vkhpp::PhysicalDevice& physical_device,
        const vkhpp::UniqueDevice& device, vkhpp::DeviceSize buffer_size,
        vkhpp::BufferUsageFlags buffer_usages,
        vkhpp::MemoryPropertyFlags bufferMemoryProperties) {
    const vkhpp::BufferCreateInfo bufferCreateInfo = {
        .size = static_cast<VkDeviceSize>(buffer_size),
        .usage = buffer_usages,
        .sharingMode = vkhpp::SharingMode::eExclusive,
    };
    auto buffer = VK_EXPECT_RV(device->createBufferUnique(bufferCreateInfo));

    vkhpp::MemoryRequirements bufferMemoryRequirements{};
    device->getBufferMemoryRequirements(*buffer, &bufferMemoryRequirements);

    const auto bufferMemoryType =
        GetMemoryType(physical_device,
                    bufferMemoryRequirements.memoryTypeBits,
                    bufferMemoryProperties);

    const vkhpp::MemoryAllocateInfo bufferMemoryAllocateInfo = {
        .allocationSize = bufferMemoryRequirements.size,
        .memoryTypeIndex = bufferMemoryType,
    };
    auto bufferMemory = VK_EXPECT_RV(device->allocateMemoryUnique(bufferMemoryAllocateInfo));

    VK_EXPECT_RESULT(device->bindBufferMemory(*buffer, *bufferMemory, 0));

    return Vk::BufferWithMemory{
        .buffer = std::move(buffer),
        .bufferMemory = std::move(bufferMemory),
    };
}

/*static*/
gfxstream::expected<Vk, vkhpp::Result> Vk::Load(
        const std::vector<std::string>& requestedInstanceExtensions,
        const std::vector<std::string>& requestedInstanceLayers,
        const std::vector<std::string>& requestedDeviceExtensions) {
    vkhpp::DynamicLoader loader;

    VULKAN_HPP_DEFAULT_DISPATCHER.init(
        loader.getProcAddress<PFN_vkGetInstanceProcAddr>(
            "vkGetInstanceProcAddr"));

    std::vector<const char*> requestedInstanceExtensionsChars;
    requestedInstanceExtensionsChars.reserve(requestedInstanceExtensions.size());
    for (const auto& e : requestedInstanceExtensions) {
        requestedInstanceExtensionsChars.push_back(e.c_str());
    }
    if (kEnableValidationLayers) {
        requestedInstanceExtensionsChars.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
    }

    std::vector<const char*> requestedInstanceLayersChars;
    requestedInstanceLayersChars.reserve(requestedInstanceLayers.size());
    for (const auto& l : requestedInstanceLayers) {
        requestedInstanceLayersChars.push_back(l.c_str());
    }

    const vkhpp::ApplicationInfo applicationInfo = {
        .pApplicationName = "Cuttlefish Graphics Detector",
        .applicationVersion = 1,
        .pEngineName = "Cuttlefish Graphics Detector",
        .engineVersion = 1,
        .apiVersion = VK_API_VERSION_1_2,
    };
    const vkhpp::InstanceCreateInfo instanceCreateInfo = {
        .pApplicationInfo = &applicationInfo,
        .enabledLayerCount = static_cast<uint32_t>(requestedInstanceLayersChars.size()),
        .ppEnabledLayerNames = requestedInstanceLayersChars.data(),
        .enabledExtensionCount = static_cast<uint32_t>(requestedInstanceExtensionsChars.size()),
        .ppEnabledExtensionNames = requestedInstanceExtensionsChars.data(),
    };

    auto instance = VK_EXPECT_RV(vkhpp::createInstanceUnique(instanceCreateInfo));

    VULKAN_HPP_DEFAULT_DISPATCHER.init(*instance);

    std::optional<vkhpp::UniqueDebugUtilsMessengerEXT> debugMessenger;
    if (kEnableValidationLayers) {
        const vkhpp::DebugUtilsMessengerCreateInfoEXT debugCreateInfo = {
            .messageSeverity = vkhpp::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose |
                            vkhpp::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
                            vkhpp::DebugUtilsMessageSeverityFlagBitsEXT::eError,
            .messageType = vkhpp::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
                        vkhpp::DebugUtilsMessageTypeFlagBitsEXT::eValidation |
                        vkhpp::DebugUtilsMessageTypeFlagBitsEXT::ePerformance,
            .pfnUserCallback = VulkanDebugCallback,
            .pUserData = nullptr,
        };
        debugMessenger = VK_EXPECT_RV(instance->createDebugUtilsMessengerEXTUnique(debugCreateInfo));
    }

    const auto physicalDevices = VK_EXPECT_RV(instance->enumeratePhysicalDevices());
    vkhpp::PhysicalDevice physicalDevice = std::move(physicalDevices[0]);


    std::unordered_set<std::string> availableDeviceExtensions;
    {
        const auto exts = VK_EXPECT_RV(physicalDevice.enumerateDeviceExtensionProperties());
        for (const auto& ext : exts) {
            availableDeviceExtensions.emplace(ext.extensionName);
        }
    }

    const auto features2 =
        physicalDevice
            .getFeatures2<vkhpp::PhysicalDeviceFeatures2,  //
                            vkhpp::PhysicalDeviceSamplerYcbcrConversionFeatures>();

    bool ycbcr_conversion_needed = false;

    std::vector<const char*> requestedDeviceExtensionsChars;
    requestedDeviceExtensionsChars.reserve(requestedDeviceExtensions.size());
    for (const auto& e : requestedDeviceExtensions) {
        if (e == std::string(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME)) {
            // The interface of VK_KHR_sampler_ycbcr_conversion was promoted to core
            // in Vulkan 1.1 but the feature/functionality is still optional. Check
            // here:
            const auto& sampler_features =
                features2.get<vkhpp::PhysicalDeviceSamplerYcbcrConversionFeatures>();

            if (sampler_features.samplerYcbcrConversion == VK_FALSE) {
                return gfxstream::unexpected(vkhpp::Result::eErrorExtensionNotPresent);
            }
            ycbcr_conversion_needed = true;
        } else {
            if (availableDeviceExtensions.find(e) == availableDeviceExtensions.end()) {
                return gfxstream::unexpected(vkhpp::Result::eErrorExtensionNotPresent);
            }
            requestedDeviceExtensionsChars.push_back(e.c_str());
        }
    }

    uint32_t queueFamilyIndex = -1;
    {
        const auto props = physicalDevice.getQueueFamilyProperties();
        for (uint32_t i = 0; i < props.size(); i++) {
            const auto& prop = props[i];
            if (prop.queueFlags & vkhpp::QueueFlagBits::eGraphics) {
                queueFamilyIndex = i;
                break;
            }
        }
    }

    const float queue_priority = 1.0f;
    const vkhpp::DeviceQueueCreateInfo device_queue_create_info = {
        .queueFamilyIndex = queueFamilyIndex,
        .queueCount = 1,
        .pQueuePriorities = &queue_priority,
    };
    const vkhpp::PhysicalDeviceVulkan11Features device_enable_features = {
        .samplerYcbcrConversion = ycbcr_conversion_needed,
    };
    const vkhpp::DeviceCreateInfo deviceCreateInfo = {
        .pNext = &device_enable_features,
        .queueCreateInfoCount = 1,
        .pQueueCreateInfos = &device_queue_create_info,
        .enabledLayerCount = static_cast<uint32_t>(requestedInstanceLayersChars.size()),
        .ppEnabledLayerNames = requestedInstanceLayersChars.data(),
        .enabledExtensionCount = static_cast<uint32_t>(requestedDeviceExtensionsChars.size()),
        .ppEnabledExtensionNames = requestedDeviceExtensionsChars.data(),
    };
    auto device = VK_EXPECT_RV(physicalDevice.createDeviceUnique(deviceCreateInfo));
    auto queue = device->getQueue(queueFamilyIndex, 0);

    const vkhpp::CommandPoolCreateInfo commandPoolCreateInfo = {
        .queueFamilyIndex = queueFamilyIndex,
    };
    auto commandPool = VK_EXPECT_RV(device->createCommandPoolUnique(commandPoolCreateInfo));

    auto stagingBuffer =
        VK_EXPECT(DoCreateBuffer(physicalDevice, device, kStagingBufferSize,
                                 vkhpp::BufferUsageFlagBits::eTransferDst |
                                    vkhpp::BufferUsageFlagBits::eTransferSrc,
                                 vkhpp::MemoryPropertyFlagBits::eHostVisible |
                                    vkhpp::MemoryPropertyFlagBits::eHostCoherent));

    return Vk(std::move(loader),
              std::move(instance),
              std::move(debugMessenger),
              std::move(physicalDevice),
              std::move(device),
              std::move(queue),
              queueFamilyIndex,
              std::move(commandPool),
              std::move(stagingBuffer.buffer),
              std::move(stagingBuffer.bufferMemory));
}

gfxstream::expected<Vk::BufferWithMemory, vkhpp::Result> Vk::CreateBuffer(
    vkhpp::DeviceSize bufferSize,
    vkhpp::BufferUsageFlags bufferUsages,
    vkhpp::MemoryPropertyFlags bufferMemoryProperties) {
  return DoCreateBuffer(mPhysicalDevice,
                        mDevice,
                        bufferSize,
                        bufferUsages,
                        bufferMemoryProperties);
}

gfxstream::expected<Vk::BufferWithMemory, vkhpp::Result> Vk::CreateBufferWithData(
        vkhpp::DeviceSize bufferSize,
        vkhpp::BufferUsageFlags bufferUsages,
        vkhpp::MemoryPropertyFlags bufferMemoryProperties,
        const uint8_t* buffer_data) {
    auto buffer = VK_EXPECT(CreateBuffer(
        bufferSize,
        bufferUsages | vkhpp::BufferUsageFlagBits::eTransferDst,
        bufferMemoryProperties));

    void* mapped = VK_EXPECT_RV(mDevice->mapMemory(*mStagingBufferMemory, 0, kStagingBufferSize));

    std::memcpy(mapped, buffer_data, bufferSize);

    mDevice->unmapMemory(*mStagingBufferMemory);

    DoCommandsImmediate([&](vkhpp::UniqueCommandBuffer& cmd) {
        const std::vector<vkhpp::BufferCopy> regions = {
            vkhpp::BufferCopy{
                .srcOffset = 0,
                .dstOffset = 0,
                .size = bufferSize,
            },
        };
        cmd->copyBuffer(*mStagingBuffer, *buffer.buffer, regions);
        return vkhpp::Result::eSuccess;
    });

    return std::move(buffer);
}

gfxstream::expected<Vk::ImageWithMemory, vkhpp::Result> Vk::CreateImage(
        uint32_t width,
        uint32_t height,
        vkhpp::Format format,
        vkhpp::ImageUsageFlags usages,
        vkhpp::MemoryPropertyFlags memoryProperties,
        vkhpp::ImageLayout returnedLayout) {
    const vkhpp::ImageCreateInfo imageCreateInfo = {
        .imageType = vkhpp::ImageType::e2D,
        .format = format,
        .extent = {
            .width = width,
            .height = height,
            .depth = 1,
        },
        .mipLevels = 1,
        .arrayLayers = 1,
        .samples = vkhpp::SampleCountFlagBits::e1,
        .tiling = vkhpp::ImageTiling::eOptimal,
        .usage = usages,
        .sharingMode = vkhpp::SharingMode::eExclusive,
        .initialLayout = vkhpp::ImageLayout::eUndefined,
    };
    auto image = VK_EXPECT_RV(mDevice->createImageUnique(imageCreateInfo));

    const auto memoryRequirements = mDevice->getImageMemoryRequirements(*image);
    const uint32_t memoryIndex =
        GetMemoryType(mPhysicalDevice,
                      memoryRequirements.memoryTypeBits,
                      memoryProperties);

    const vkhpp::MemoryAllocateInfo imageMemoryAllocateInfo = {
        .allocationSize = memoryRequirements.size,
        .memoryTypeIndex = memoryIndex,
    };
    auto imageMemory = VK_EXPECT_RV(mDevice->allocateMemoryUnique(imageMemoryAllocateInfo));

    mDevice->bindImageMemory(*image, *imageMemory, 0);

    const vkhpp::ImageViewCreateInfo imageViewCreateInfo = {
        .image = *image,
        .viewType = vkhpp::ImageViewType::e2D,
        .format = format,
        .components = {
            .r = vkhpp::ComponentSwizzle::eIdentity,
            .g = vkhpp::ComponentSwizzle::eIdentity,
            .b = vkhpp::ComponentSwizzle::eIdentity,
            .a = vkhpp::ComponentSwizzle::eIdentity,
        },
        .subresourceRange = {
            .aspectMask = vkhpp::ImageAspectFlagBits::eColor,
            .baseMipLevel = 0,
            .levelCount = 1,
            .baseArrayLayer = 0,
            .layerCount = 1,
        },
    };
    auto imageView = VK_EXPECT_RV(mDevice->createImageViewUnique(imageViewCreateInfo));

    VK_EXPECT_RESULT(DoCommandsImmediate([&](vkhpp::UniqueCommandBuffer& cmd) {
        const std::vector<vkhpp::ImageMemoryBarrier> imageMemoryBarriers = {
            vkhpp::ImageMemoryBarrier{
                .srcAccessMask = {},
                .dstAccessMask = vkhpp::AccessFlagBits::eTransferWrite,
                .oldLayout = vkhpp::ImageLayout::eUndefined,
                .newLayout = returnedLayout,
                .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
                .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
                .image = *image,
                .subresourceRange = {
                    .aspectMask = vkhpp::ImageAspectFlagBits::eColor,
                    .baseMipLevel = 0,
                    .levelCount = 1,
                    .baseArrayLayer = 0,
                    .layerCount = 1,
                },
            },
        };
        cmd->pipelineBarrier(
            /*srcStageMask=*/vkhpp::PipelineStageFlagBits::eAllCommands,
            /*dstStageMask=*/vkhpp::PipelineStageFlagBits::eAllCommands,
            /*dependencyFlags=*/{},
            /*memoryBarriers=*/{},
            /*bufferMemoryBarriers=*/{},
            /*imageMemoryBarriers=*/imageMemoryBarriers);

        return vkhpp::Result::eSuccess;
    }));

    return ImageWithMemory{
        .image = std::move(image),
        .imageMemory = std::move(imageMemory),
        .imageView = std::move(imageView),
    };
}

gfxstream::expected<std::vector<uint8_t>, vkhpp::Result> Vk::DownloadImage(
        uint32_t width,
        uint32_t height,
        const vkhpp::UniqueImage& image,
        vkhpp::ImageLayout currentLayout,
        vkhpp::ImageLayout returnedLayout) {
    VK_EXPECT_RESULT(
        DoCommandsImmediate([&](vkhpp::UniqueCommandBuffer& cmd) {
            if (currentLayout != vkhpp::ImageLayout::eTransferSrcOptimal) {
            const std::vector<vkhpp::ImageMemoryBarrier> imageMemoryBarriers = {
                vkhpp::ImageMemoryBarrier{
                    .srcAccessMask = vkhpp::AccessFlagBits::eMemoryRead |
                                     vkhpp::AccessFlagBits::eMemoryWrite,
                    .dstAccessMask = vkhpp::AccessFlagBits::eTransferRead,
                    .oldLayout = currentLayout,
                    .newLayout = vkhpp::ImageLayout::eTransferSrcOptimal,
                    .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
                    .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
                    .image = *image,
                    .subresourceRange = {
                        .aspectMask = vkhpp::ImageAspectFlagBits::eColor,
                        .baseMipLevel = 0,
                        .levelCount = 1,
                        .baseArrayLayer = 0,
                        .layerCount = 1,
                    },
                },
            };
            cmd->pipelineBarrier(
                /*srcStageMask=*/vkhpp::PipelineStageFlagBits::eAllCommands,
                /*dstStageMask=*/vkhpp::PipelineStageFlagBits::eAllCommands,
                /*dependencyFlags=*/{},
                /*memoryBarriers=*/{},
                /*bufferMemoryBarriers=*/{},
                /*imageMemoryBarriers=*/imageMemoryBarriers);
            }

            const std::vector<vkhpp::BufferImageCopy> regions = {
                vkhpp::BufferImageCopy{
                    .bufferOffset = 0,
                    .bufferRowLength = 0,
                    .bufferImageHeight = 0,
                    .imageSubresource =
                        {
                            .aspectMask = vkhpp::ImageAspectFlagBits::eColor,
                            .mipLevel = 0,
                            .baseArrayLayer = 0,
                            .layerCount = 1,
                        },
                    .imageOffset =
                        {
                            .x = 0,
                            .y = 0,
                            .z = 0,
                        },
                    .imageExtent =
                        {
                            .width = width,
                            .height = height,
                            .depth = 1,
                        },
                },
            };
            cmd->copyImageToBuffer(*image,
                                   vkhpp::ImageLayout::eTransferSrcOptimal,
                                   *mStagingBuffer, regions);

            if (returnedLayout != vkhpp::ImageLayout::eTransferSrcOptimal) {
                const std::vector<vkhpp::ImageMemoryBarrier> imageMemoryBarriers = {
                    vkhpp::ImageMemoryBarrier{
                        .srcAccessMask = vkhpp::AccessFlagBits::eTransferRead,
                        .dstAccessMask = vkhpp::AccessFlagBits::eMemoryRead |
                                         vkhpp::AccessFlagBits::eMemoryWrite,
                        .oldLayout = vkhpp::ImageLayout::eTransferSrcOptimal,
                        .newLayout = returnedLayout,
                        .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
                        .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
                        .image = *image,
                        .subresourceRange = {
                                .aspectMask = vkhpp::ImageAspectFlagBits::eColor,
                                .baseMipLevel = 0,
                                .levelCount = 1,
                                .baseArrayLayer = 0,
                                .layerCount = 1,
                            },
                    },
                };
                cmd->pipelineBarrier(
                    /*srcStageMask=*/vkhpp::PipelineStageFlagBits::eAllCommands,
                    /*dstStageMask=*/vkhpp::PipelineStageFlagBits::eAllCommands,
                    /*dependencyFlags=*/{},
                    /*memoryBarriers=*/{},
                    /*bufferMemoryBarriers=*/{},
                    /*imageMemoryBarriers=*/imageMemoryBarriers);
            }

            return vkhpp::Result::eSuccess;
        }));

    auto* mapped = reinterpret_cast<uint8_t*>(
        VK_EXPECT_RV(mDevice->mapMemory(*mStagingBufferMemory, 0, kStagingBufferSize)));

    std::vector<uint8_t> outPixels;
    outPixels.resize(width * height * 4);

    std::memcpy(outPixels.data(), mapped, outPixels.size());

    mDevice->unmapMemory(*mStagingBufferMemory);

    return outPixels;
}

gfxstream::expected<Vk::YuvImageWithMemory, vkhpp::Result> Vk::CreateYuvImage(
        uint32_t width,
        uint32_t height,
        vkhpp::ImageUsageFlags usages,
        vkhpp::MemoryPropertyFlags memoryProperties,
        vkhpp::ImageLayout layout) {
    const vkhpp::SamplerYcbcrConversionCreateInfo conversionCreateInfo = {
        .format = vkhpp::Format::eG8B8R83Plane420Unorm,
        .ycbcrModel = vkhpp::SamplerYcbcrModelConversion::eYcbcr601,
        .ycbcrRange = vkhpp::SamplerYcbcrRange::eItuNarrow,
        .components = {
            .r = vkhpp::ComponentSwizzle::eIdentity,
            .g = vkhpp::ComponentSwizzle::eIdentity,
            .b = vkhpp::ComponentSwizzle::eIdentity,
            .a = vkhpp::ComponentSwizzle::eIdentity,
        },
        .xChromaOffset = vkhpp::ChromaLocation::eMidpoint,
        .yChromaOffset = vkhpp::ChromaLocation::eMidpoint,
        .chromaFilter = vkhpp::Filter::eLinear,
        .forceExplicitReconstruction = VK_FALSE,
    };
    auto imageSamplerConversion = VK_EXPECT_RV(mDevice->createSamplerYcbcrConversionUnique(conversionCreateInfo));

    const vkhpp::SamplerYcbcrConversionInfo samplerConversionInfo = {
        .conversion = *imageSamplerConversion,
    };
    const vkhpp::SamplerCreateInfo samplerCreateInfo = {
        .pNext = &samplerConversionInfo,
        .magFilter = vkhpp::Filter::eLinear,
        .minFilter = vkhpp::Filter::eLinear,
        .mipmapMode = vkhpp::SamplerMipmapMode::eNearest,
        .addressModeU = vkhpp::SamplerAddressMode::eClampToEdge,
        .addressModeV = vkhpp::SamplerAddressMode::eClampToEdge,
        .addressModeW = vkhpp::SamplerAddressMode::eClampToEdge,
        .mipLodBias = 0.0f,
        .anisotropyEnable = VK_FALSE,
        .maxAnisotropy = 1.0f,
        .compareEnable = VK_FALSE,
        .compareOp = vkhpp::CompareOp::eLessOrEqual,
        .minLod = 0.0f,
        .maxLod = 0.25f,
        .borderColor = vkhpp::BorderColor::eIntTransparentBlack,
        .unnormalizedCoordinates = VK_FALSE,
    };
    auto imageSampler = VK_EXPECT_RV(mDevice->createSamplerUnique(samplerCreateInfo));

    const vkhpp::ImageCreateInfo imageCreateInfo = {
        .imageType = vkhpp::ImageType::e2D,
        .format = vkhpp::Format::eG8B8R83Plane420Unorm,
        .extent = {
            .width = width,
            .height = height,
            .depth = 1,
        },
        .mipLevels = 1,
        .arrayLayers = 1,
        .samples = vkhpp::SampleCountFlagBits::e1,
        .tiling = vkhpp::ImageTiling::eOptimal,
        .usage = usages,
        .sharingMode = vkhpp::SharingMode::eExclusive,
        .initialLayout = vkhpp::ImageLayout::eUndefined,
    };
    auto image = VK_EXPECT_RV(mDevice->createImageUnique(imageCreateInfo));

    const auto memoryRequirements = mDevice->getImageMemoryRequirements(*image);

    const uint32_t memoryIndex =
        GetMemoryType(mPhysicalDevice,
                      memoryRequirements.memoryTypeBits,
                      memoryProperties);

    const vkhpp::MemoryAllocateInfo imageMemoryAllocateInfo = {
        .allocationSize = memoryRequirements.size,
        .memoryTypeIndex = memoryIndex,
    };
    auto imageMemory = VK_EXPECT_RV(mDevice->allocateMemoryUnique(imageMemoryAllocateInfo));

    mDevice->bindImageMemory(*image, *imageMemory, 0);

    const vkhpp::ImageViewCreateInfo imageViewCreateInfo = {
        .pNext = &samplerConversionInfo,
        .image = *image,
        .viewType = vkhpp::ImageViewType::e2D,
        .format = vkhpp::Format::eG8B8R83Plane420Unorm,
        .components = {
            .r = vkhpp::ComponentSwizzle::eIdentity,
            .g = vkhpp::ComponentSwizzle::eIdentity,
            .b = vkhpp::ComponentSwizzle::eIdentity,
            .a = vkhpp::ComponentSwizzle::eIdentity,
        },
        .subresourceRange = {
            .aspectMask = vkhpp::ImageAspectFlagBits::eColor,
            .baseMipLevel = 0,
            .levelCount = 1,
            .baseArrayLayer = 0,
            .layerCount = 1,
        },
    };
    auto imageView = VK_EXPECT_RV(mDevice->createImageViewUnique(imageViewCreateInfo));

    VK_EXPECT_RESULT(DoCommandsImmediate([&](vkhpp::UniqueCommandBuffer& cmd) {
        const std::vector<vkhpp::ImageMemoryBarrier> imageMemoryBarriers = {
            vkhpp::ImageMemoryBarrier{
                .srcAccessMask = {},
                .dstAccessMask = vkhpp::AccessFlagBits::eTransferWrite,
                .oldLayout = vkhpp::ImageLayout::eUndefined,
                .newLayout = layout,
                .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
                .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
                .image = *image,
                .subresourceRange = {
                    .aspectMask = vkhpp::ImageAspectFlagBits::eColor,
                    .baseMipLevel = 0,
                    .levelCount = 1,
                    .baseArrayLayer = 0,
                    .layerCount = 1,
                },

            },
        };
        cmd->pipelineBarrier(
            /*srcStageMask=*/vkhpp::PipelineStageFlagBits::eAllCommands,
            /*dstStageMask=*/vkhpp::PipelineStageFlagBits::eAllCommands,
            /*dependencyFlags=*/{},
            /*memoryBarriers=*/{},
            /*bufferMemoryBarriers=*/{},
            /*imageMemoryBarriers=*/imageMemoryBarriers);
        return vkhpp::Result::eSuccess;
    }));

    return YuvImageWithMemory{
        .imageSamplerConversion = std::move(imageSamplerConversion),
        .imageSampler = std::move(imageSampler),
        .imageMemory = std::move(imageMemory),
        .image = std::move(image),
        .imageView = std::move(imageView),
    };
}

vkhpp::Result Vk::LoadYuvImage(
        const vkhpp::UniqueImage& image,
        uint32_t width,
        uint32_t height,
        const std::vector<uint8_t>& imageDataY,
        const std::vector<uint8_t>& imageDataU,
        const std::vector<uint8_t>& imageDataV,
        vkhpp::ImageLayout currentLayout,
        vkhpp::ImageLayout returnedLayout) {
    auto* mapped = reinterpret_cast<uint8_t*>(VK_TRY_RV(mDevice->mapMemory(*mStagingBufferMemory, 0, kStagingBufferSize)));

    const VkDeviceSize yOffset = 0;
    const VkDeviceSize uOffset = imageDataY.size();
    const VkDeviceSize vOffset = imageDataY.size() + imageDataU.size();
    std::memcpy(mapped + yOffset, imageDataY.data(), imageDataY.size());
    std::memcpy(mapped + uOffset, imageDataU.data(), imageDataU.size());
    std::memcpy(mapped + vOffset, imageDataV.data(), imageDataV.size());
    mDevice->unmapMemory(*mStagingBufferMemory);

    return DoCommandsImmediate([&](vkhpp::UniqueCommandBuffer& cmd) {
        if (currentLayout != vkhpp::ImageLayout::eTransferDstOptimal) {
        const std::vector<vkhpp::ImageMemoryBarrier> imageMemoryBarriers = {
            vkhpp::ImageMemoryBarrier{
                .srcAccessMask = vkhpp::AccessFlagBits::eMemoryRead |
                                vkhpp::AccessFlagBits::eMemoryWrite,
                .dstAccessMask = vkhpp::AccessFlagBits::eTransferWrite,
                .oldLayout = currentLayout,
                .newLayout = vkhpp::ImageLayout::eTransferDstOptimal,
                .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
                .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
                .image = *image,
                .subresourceRange = {
                    .aspectMask = vkhpp::ImageAspectFlagBits::eColor,
                    .baseMipLevel = 0,
                    .levelCount = 1,
                    .baseArrayLayer = 0,
                    .layerCount = 1,
                },

            },
        };
        cmd->pipelineBarrier(
            /*srcStageMask=*/vkhpp::PipelineStageFlagBits::eAllCommands,
            /*dstStageMask=*/vkhpp::PipelineStageFlagBits::eAllCommands,
            /*dependencyFlags=*/{},
            /*memoryBarriers=*/{},
            /*bufferMemoryBarriers=*/{},
            /*imageMemoryBarriers=*/imageMemoryBarriers);
        }

        const std::vector<vkhpp::BufferImageCopy> imageCopyRegions = {
            vkhpp::BufferImageCopy{
                .bufferOffset = yOffset,
                .bufferRowLength = 0,
                .bufferImageHeight = 0,
                .imageSubresource = {
                    .aspectMask = vkhpp::ImageAspectFlagBits::ePlane0,
                    .mipLevel = 0,
                    .baseArrayLayer = 0,
                    .layerCount = 1,
                },
                .imageOffset = {
                    .x = 0,
                    .y = 0,
                    .z = 0,
                },
                .imageExtent = {
                    .width = width,
                    .height = height,
                    .depth = 1,
                },
            },
            vkhpp::BufferImageCopy{
                .bufferOffset = uOffset,
                .bufferRowLength = 0,
                .bufferImageHeight = 0,
                .imageSubresource = {
                    .aspectMask = vkhpp::ImageAspectFlagBits::ePlane1,
                    .mipLevel = 0,
                    .baseArrayLayer = 0,
                    .layerCount = 1,
                },
                .imageOffset = {
                    .x = 0,
                    .y = 0,
                    .z = 0,
                },
                .imageExtent = {
                    .width = width / 2,
                    .height = height / 2,
                    .depth = 1,
                },
            },
            vkhpp::BufferImageCopy{
                .bufferOffset = vOffset,
                .bufferRowLength = 0,
                .bufferImageHeight = 0,
                .imageSubresource = {
                    .aspectMask = vkhpp::ImageAspectFlagBits::ePlane2,
                    .mipLevel = 0,
                    .baseArrayLayer = 0,
                    .layerCount = 1,
                },
                .imageOffset = {
                    .x = 0,
                    .y = 0,
                    .z = 0,
                },
                .imageExtent = {
                    .width = width / 2,
                    .height = height / 2,
                    .depth = 1,
                },
            },
        };
        cmd->copyBufferToImage(*mStagingBuffer,
                               *image,
                               vkhpp::ImageLayout::eTransferDstOptimal,
                               imageCopyRegions);

        if (returnedLayout != vkhpp::ImageLayout::eTransferDstOptimal) {
            const std::vector<vkhpp::ImageMemoryBarrier> imageMemoryBarriers = {
                vkhpp::ImageMemoryBarrier{
                    .srcAccessMask = vkhpp::AccessFlagBits::eTransferWrite,
                    .dstAccessMask = vkhpp::AccessFlagBits::eMemoryRead |
                                    vkhpp::AccessFlagBits::eMemoryWrite,
                    .oldLayout = vkhpp::ImageLayout::eTransferDstOptimal,
                    .newLayout = returnedLayout,
                    .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
                    .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
                    .image = *image,
                    .subresourceRange = {
                        .aspectMask = vkhpp::ImageAspectFlagBits::eColor,
                        .baseMipLevel = 0,
                        .levelCount = 1,
                        .baseArrayLayer = 0,
                        .layerCount = 1,
                    },
                },
            };
            cmd->pipelineBarrier(
                /*srcStageMask=*/vkhpp::PipelineStageFlagBits::eAllCommands,
                /*dstStageMask=*/vkhpp::PipelineStageFlagBits::eAllCommands,
                /*dependencyFlags=*/{},
                /*memoryBarriers=*/{},
                /*bufferMemoryBarriers=*/{},
                /*imageMemoryBarriers=*/imageMemoryBarriers);
        }
        return vkhpp::Result::eSuccess;
    });
}

gfxstream::expected<Vk::FramebufferWithAttachments, vkhpp::Result>
Vk::CreateFramebuffer(
        uint32_t width,
        uint32_t height,
        vkhpp::Format color_format,
        vkhpp::Format depth_format) {
    std::optional<Vk::ImageWithMemory> colorAttachment;
    if (color_format != vkhpp::Format::eUndefined) {
        colorAttachment =
            GFXSTREAM_EXPECT(CreateImage(width, height, color_format,
                                vkhpp::ImageUsageFlagBits::eColorAttachment |
                                    vkhpp::ImageUsageFlagBits::eTransferSrc,
                                vkhpp::MemoryPropertyFlagBits::eDeviceLocal,
                                vkhpp::ImageLayout::eColorAttachmentOptimal));
    }

    std::optional<Vk::ImageWithMemory> depthAttachment;
    if (depth_format != vkhpp::Format::eUndefined) {
        depthAttachment =
            GFXSTREAM_EXPECT(CreateImage(width, height, depth_format,
                                vkhpp::ImageUsageFlagBits::eDepthStencilAttachment |
                                    vkhpp::ImageUsageFlagBits::eTransferSrc,
                                vkhpp::MemoryPropertyFlagBits::eDeviceLocal,
                                vkhpp::ImageLayout::eDepthStencilAttachmentOptimal));
    }

    std::vector<vkhpp::AttachmentDescription> attachments;

    std::optional<vkhpp::AttachmentReference> colorAttachment_reference;
    if (color_format != vkhpp::Format::eUndefined) {
        attachments.push_back(vkhpp::AttachmentDescription{
            .format = color_format,
            .samples = vkhpp::SampleCountFlagBits::e1,
            .loadOp = vkhpp::AttachmentLoadOp::eClear,
            .storeOp = vkhpp::AttachmentStoreOp::eStore,
            .stencilLoadOp = vkhpp::AttachmentLoadOp::eClear,
            .stencilStoreOp = vkhpp::AttachmentStoreOp::eStore,
            .initialLayout = vkhpp::ImageLayout::eColorAttachmentOptimal,
            .finalLayout = vkhpp::ImageLayout::eColorAttachmentOptimal,
        });

        colorAttachment_reference = vkhpp::AttachmentReference{
            .attachment = static_cast<uint32_t>(attachments.size() - 1),
            .layout = vkhpp::ImageLayout::eColorAttachmentOptimal,
        };
    }

    std::optional<vkhpp::AttachmentReference> depthAttachment_reference;
    if (depth_format != vkhpp::Format::eUndefined) {
        attachments.push_back(vkhpp::AttachmentDescription{
            .format = depth_format,
            .samples = vkhpp::SampleCountFlagBits::e1,
            .loadOp = vkhpp::AttachmentLoadOp::eClear,
            .storeOp = vkhpp::AttachmentStoreOp::eStore,
            .stencilLoadOp = vkhpp::AttachmentLoadOp::eClear,
            .stencilStoreOp = vkhpp::AttachmentStoreOp::eStore,
            .initialLayout = vkhpp::ImageLayout::eColorAttachmentOptimal,
            .finalLayout = vkhpp::ImageLayout::eColorAttachmentOptimal,
        });

        depthAttachment_reference = vkhpp::AttachmentReference{
            .attachment = static_cast<uint32_t>(attachments.size() - 1),
            .layout = vkhpp::ImageLayout::eDepthStencilAttachmentOptimal,
        };
    }

    vkhpp::SubpassDependency dependency = {
        .srcSubpass = 0,
        .dstSubpass = 0,
        .srcStageMask = {},
        .dstStageMask = vkhpp::PipelineStageFlagBits::eFragmentShader,
        .srcAccessMask = {},
        .dstAccessMask = vkhpp::AccessFlagBits::eInputAttachmentRead,
        .dependencyFlags = vkhpp::DependencyFlagBits::eByRegion,
    };
    if (color_format != vkhpp::Format::eUndefined) {
        dependency.srcStageMask |=
            vkhpp::PipelineStageFlagBits::eColorAttachmentOutput;
        dependency.dstStageMask |=
            vkhpp::PipelineStageFlagBits::eColorAttachmentOutput;
        dependency.srcAccessMask |= vkhpp::AccessFlagBits::eColorAttachmentWrite;
    }
    if (depth_format != vkhpp::Format::eUndefined) {
        dependency.srcStageMask |=
            vkhpp::PipelineStageFlagBits::eColorAttachmentOutput;
        dependency.dstStageMask |=
            vkhpp::PipelineStageFlagBits::eColorAttachmentOutput;
        dependency.srcAccessMask |= vkhpp::AccessFlagBits::eColorAttachmentWrite;
    }

    vkhpp::SubpassDescription subpass = {
        .pipelineBindPoint = vkhpp::PipelineBindPoint::eGraphics,
        .inputAttachmentCount = 0,
        .pInputAttachments = nullptr,
        .colorAttachmentCount = 0,
        .pColorAttachments = nullptr,
        .pResolveAttachments = nullptr,
        .pDepthStencilAttachment = nullptr,
        .pPreserveAttachments = nullptr,
    };
    if (color_format != vkhpp::Format::eUndefined) {
        subpass.colorAttachmentCount = 1;
        subpass.pColorAttachments = &*colorAttachment_reference;
    }
    if (depth_format != vkhpp::Format::eUndefined) {
        subpass.pDepthStencilAttachment = &*depthAttachment_reference;
    }

    const vkhpp::RenderPassCreateInfo renderpassCreateInfo = {
        .attachmentCount = static_cast<uint32_t>(attachments.size()),
        .pAttachments = attachments.data(),
        .subpassCount = 1,
        .pSubpasses = &subpass,
        .dependencyCount = 1,
        .pDependencies = &dependency,
    };
    auto renderpass = VK_EXPECT_RV(mDevice->createRenderPassUnique(renderpassCreateInfo));

    std::vector<vkhpp::ImageView> framebufferAttachments;
    if (colorAttachment) {
        framebufferAttachments.push_back(*colorAttachment->imageView);
    }
    if (depthAttachment) {
        framebufferAttachments.push_back(*depthAttachment->imageView);
    }
    const vkhpp::FramebufferCreateInfo framebufferCreateInfo = {
        .renderPass = *renderpass,
        .attachmentCount = static_cast<uint32_t>(framebufferAttachments.size()),
        .pAttachments = framebufferAttachments.data(),
        .width = width,
        .height = height,
        .layers = 1,
    };
    auto framebuffer = VK_EXPECT_RV(mDevice->createFramebufferUnique(framebufferCreateInfo));

    return Vk::FramebufferWithAttachments{
        .colorAttachment = std::move(colorAttachment),
        .depthAttachment = std::move(depthAttachment),
        .renderpass = std::move(renderpass),
        .framebuffer = std::move(framebuffer),
    };
}

vkhpp::Result Vk::DoCommandsImmediate(
        const std::function<vkhpp::Result(vkhpp::UniqueCommandBuffer&)>& func,
        const std::vector<vkhpp::UniqueSemaphore>& semaphores_wait,
        const std::vector<vkhpp::UniqueSemaphore>& semaphores_signal) {
    const vkhpp::CommandBufferAllocateInfo commandBufferAllocateInfo = {
        .commandPool = *mCommandPool,
        .level = vkhpp::CommandBufferLevel::ePrimary,
        .commandBufferCount = 1,
    };
    auto commandBuffers = VK_TRY_RV(mDevice->allocateCommandBuffersUnique(commandBufferAllocateInfo));
    auto commandBuffer = std::move(commandBuffers[0]);

    const vkhpp::CommandBufferBeginInfo commandBufferBeginInfo = {
        .flags = vkhpp::CommandBufferUsageFlagBits::eOneTimeSubmit,
    };
    commandBuffer->begin(commandBufferBeginInfo);
    VK_TRY(func(commandBuffer));
    commandBuffer->end();

    std::vector<vkhpp::CommandBuffer> commandBufferHandles;
    commandBufferHandles.push_back(*commandBuffer);

    std::vector<vkhpp::Semaphore> semaphoreHandlesWait;
    semaphoreHandlesWait.reserve(semaphores_wait.size());
    for (const auto& s : semaphores_wait) {
        semaphoreHandlesWait.emplace_back(*s);
    }

    std::vector<vkhpp::Semaphore> semaphoreHandlesSignal;
    semaphoreHandlesSignal.reserve(semaphores_signal.size());
    for (const auto& s : semaphores_signal) {
        semaphoreHandlesSignal.emplace_back(*s);
    }

    vkhpp::SubmitInfo submitInfo = {
        .commandBufferCount = static_cast<uint32_t>(commandBufferHandles.size()),
        .pCommandBuffers = commandBufferHandles.data(),
    };
    if (!semaphoreHandlesWait.empty()) {
        submitInfo.waitSemaphoreCount = static_cast<uint32_t>(semaphoreHandlesWait.size());
        submitInfo.pWaitSemaphores = semaphoreHandlesWait.data();
    }
    if (!semaphoreHandlesSignal.empty()) {
        submitInfo.signalSemaphoreCount = static_cast<uint32_t>(semaphoreHandlesSignal.size());
        submitInfo.pSignalSemaphores = semaphoreHandlesSignal.data();
    }
    mQueue.submit(submitInfo);
    mQueue.waitIdle();

    return vkhpp::Result::eSuccess;
}

}  // namespace gfxstream
