/*
 * Copyright 2020 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "tools/gpu/vk/VkYcbcrSamplerHelper.h"

#if defined(SK_VULKAN)

#include "include/gpu/vk/VulkanTypes.h"
#include "src/gpu/vk/VulkanInterface.h"

#if defined(SK_GRAPHITE)
#include "include/gpu/GpuTypes.h"
#include "include/gpu/graphite/BackendTexture.h"
#include "include/gpu/graphite/Recorder.h"
#include "include/gpu/graphite/vk/VulkanGraphiteTypes.h"
#include "src/gpu/graphite/vk/VulkanGraphiteUtils.h"
#include "src/gpu/graphite/vk/VulkanSharedContext.h"
#endif

#if defined(SK_GANESH)
#include "include/gpu/ganesh/GrDirectContext.h"
#include "include/gpu/ganesh/vk/GrVkBackendSurface.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/vk/GrVkGpu.h"
#include "src/gpu/ganesh/vk/GrVkUtil.h"
#endif

int VkYcbcrSamplerHelper::GetExpectedY(int x, int y, int width, int height) {
    return 16 + (x + y) * 219 / (width + height - 2);
}

std::pair<int, int> VkYcbcrSamplerHelper::GetExpectedUV(int x, int y, int width, int height) {
    return { 16 + x * 224 / (width - 1), 16 + y * 224 / (height - 1) };
}

namespace {

void populate_ycbcr_image_info(VkImageCreateInfo* outImageInfo, uint32_t width, uint32_t height) {
    outImageInfo->sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
    outImageInfo->pNext = nullptr;
    outImageInfo->flags = 0;
    outImageInfo->imageType = VK_IMAGE_TYPE_2D;
    outImageInfo->format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
    outImageInfo->extent = VkExtent3D{width, height, 1};
    outImageInfo->mipLevels = 1;
    outImageInfo->arrayLayers = 1;
    outImageInfo->samples = VK_SAMPLE_COUNT_1_BIT;
    outImageInfo->tiling = VK_IMAGE_TILING_LINEAR;
    outImageInfo->usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
                          VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
    outImageInfo->sharingMode = VK_SHARING_MODE_EXCLUSIVE;
    outImageInfo->queueFamilyIndexCount = 0;
    outImageInfo->pQueueFamilyIndices = nullptr;
    outImageInfo->initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
}

bool find_memory_type_index(const VkPhysicalDeviceMemoryProperties& phyDevMemProps,
                            const VkMemoryRequirements& memoryRequirements,
                            uint32_t* memoryTypeIndex) {
    for (uint32_t i = 0; i < phyDevMemProps.memoryTypeCount; ++i) {
        if (memoryRequirements.memoryTypeBits & (1 << i)) {
            // Map host-visible memory.
            if (phyDevMemProps.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
                *memoryTypeIndex = i;
                return true;
            }
        }
    }
    return false;
}

}

#ifdef SK_GRAPHITE
// TODO(b/339211930): When graphite and ganesh can share a macro for certain Vulkan driver calls,
// much more code can be shared between this method and createGrBackendTexture.
bool VkYcbcrSamplerHelper::createBackendTexture(uint32_t width, uint32_t height) {
    // Create YCbCr image.
    VkImageCreateInfo vkImageInfo;
    populate_ycbcr_image_info(&vkImageInfo, width, height);
    SkASSERT(fImage == VK_NULL_HANDLE);

    VkResult result;
    VULKAN_CALL_RESULT(fSharedCtxt, result, CreateImage(fSharedCtxt->device(),
                                                        &vkImageInfo,
                                                        /*pAllocator=*/nullptr,
                                                        &fImage));
    if (result != VK_SUCCESS) {
        return false;
    }

    VkMemoryRequirements requirements;
    VULKAN_CALL(fSharedCtxt->interface(), GetImageMemoryRequirements(fSharedCtxt->device(),
                                                                     fImage,
                                                                     &requirements));
    uint32_t memoryTypeIndex = 0;
    const VkPhysicalDeviceMemoryProperties& phyDevMemProps =
            fSharedCtxt->vulkanCaps().physicalDeviceMemoryProperties2().memoryProperties;
    if (!find_memory_type_index(phyDevMemProps, requirements, &memoryTypeIndex)) {
        return false;
    }

    VkMemoryAllocateInfo allocInfo;
    allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
    allocInfo.pNext = nullptr;
    allocInfo.allocationSize = requirements.size;
    allocInfo.memoryTypeIndex = memoryTypeIndex;

    SkASSERT(fImageMemory == VK_NULL_HANDLE);
    VULKAN_CALL_RESULT(fSharedCtxt, result, AllocateMemory(fSharedCtxt->device(),
                                                           &allocInfo,
                                                           nullptr,
                                                           &fImageMemory));
    if (result != VK_SUCCESS) {
        return false;
    }

    // Bind image memory.
    VULKAN_CALL_RESULT(fSharedCtxt, result, BindImageMemory(fSharedCtxt->device(),
                                                            fImage,
                                                            fImageMemory,
                                                            /*memoryOffset=*/0u));
    if (result != VK_SUCCESS) {
        return false;
    }

    void* mappedBuffer;
    VULKAN_CALL_RESULT(fSharedCtxt, result, MapMemory(fSharedCtxt->device(),
                                                      fImageMemory,
                                                      /*offset=*/0u,
                                                      requirements.size,
                                                      /*flags=*/0u,
                                                      &mappedBuffer));
    if (result != VK_SUCCESS) {
        return false;
    }

    // Write Y channel.
    VkImageSubresource subresource;
    subresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
    subresource.mipLevel = 0;
    subresource.arrayLayer = 0;

    VkSubresourceLayout yLayout;
    VULKAN_CALL(fSharedCtxt->interface(),
                GetImageSubresourceLayout(fSharedCtxt->device(), fImage, &subresource, &yLayout));
    uint8_t* bufferData = reinterpret_cast<uint8_t*>(mappedBuffer) + yLayout.offset;
    for (size_t y = 0; y < height; ++y) {
        for (size_t x = 0; x < width; ++x) {
            bufferData[y * yLayout.rowPitch + x] = GetExpectedY(x, y, width, height);
        }
    }

    // Write UV channels.
    subresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
    VkSubresourceLayout uvLayout;
    VULKAN_CALL(fSharedCtxt->interface(), GetImageSubresourceLayout(fSharedCtxt->device(),
                                                                    fImage,
                                                                    &subresource,
                                                                    &uvLayout));
    bufferData = reinterpret_cast<uint8_t*>(mappedBuffer) + uvLayout.offset;
    for (size_t y = 0; y < height / 2; ++y) {
        for (size_t x = 0; x < width / 2; ++x) {
            auto [u, v] = GetExpectedUV(2*x, 2*y, width, height);
            bufferData[y * uvLayout.rowPitch + x * 2] = u;
            bufferData[y * uvLayout.rowPitch + x * 2 + 1] = v;
        }
    }

    VkMappedMemoryRange flushRange;
    flushRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
    flushRange.pNext = nullptr;
    flushRange.memory = fImageMemory;
    flushRange.offset = 0;
    flushRange.size = VK_WHOLE_SIZE;
    VULKAN_CALL_RESULT(fSharedCtxt, result,  FlushMappedMemoryRanges(fSharedCtxt->device(),
                                                                     /*memoryRangeCount=*/1,
                                                                     &flushRange));
    if (result != VK_SUCCESS) {
        return false;
    }
    VULKAN_CALL(fSharedCtxt->interface(), UnmapMemory(fSharedCtxt->device(), fImageMemory));

    // Wrap the image into SkImage.
    VkFormatProperties formatProperties;
    SkASSERT(fSharedCtxt->physDevice() != VK_NULL_HANDLE);
    VULKAN_CALL(fSharedCtxt->interface(),
                GetPhysicalDeviceFormatProperties(fSharedCtxt->physDevice(),
                                                  VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
                                                  &formatProperties));
    SkDEBUGCODE(auto linFlags = formatProperties.linearTilingFeatures;)
    SkASSERT((linFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) &&
             (linFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) &&
             (linFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT) &&
             (linFlags & VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT));

    skgpu::VulkanYcbcrConversionInfo ycbcrInfo(vkImageInfo.format,
                                               VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709,
                                               VK_SAMPLER_YCBCR_RANGE_ITU_NARROW,
                                               VK_CHROMA_LOCATION_COSITED_EVEN,
                                               VK_CHROMA_LOCATION_COSITED_EVEN,
                                               VK_FILTER_LINEAR,
                                               /*forceExplicitReconstruction=*/false,
                                               /*components=*/{},
                                               formatProperties.linearTilingFeatures);
skgpu::VulkanAlloc alloc;
    alloc.fMemory = fImageMemory;
    alloc.fOffset = 0;
    alloc.fSize = requirements.size;

    skgpu::graphite::VulkanTextureInfo imageInfo = {
            vkImageInfo.samples,
            skgpu::Mipmapped::kNo,
            VK_IMAGE_CREATE_PROTECTED_BIT,
            vkImageInfo.format,
            vkImageInfo.tiling,
            vkImageInfo.usage,
            vkImageInfo.sharingMode,
            VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT,
            ycbcrInfo};

    fTexture = skgpu::graphite::BackendTextures::MakeVulkan({(int32_t)width, (int32_t)height},
                                                            imageInfo,
                                                            VK_IMAGE_LAYOUT_PREINITIALIZED,
                                                            /*queueFamilyIndex=*/0,
                                                            fImage,
                                                            alloc);
    return true;
}
#endif // SK_GRAPHITE

#if defined(SK_GANESH)
bool VkYcbcrSamplerHelper::createGrBackendTexture(uint32_t width, uint32_t height) {
    GrVkGpu* vkGpu = this->vkGpu();
    VkResult result;

    // Create YCbCr image.
    VkImageCreateInfo vkImageInfo;
    populate_ycbcr_image_info(&vkImageInfo, width, height);
    SkASSERT(fImage == VK_NULL_HANDLE);

    GR_VK_CALL_RESULT(vkGpu, result, CreateImage(vkGpu->device(), &vkImageInfo, nullptr, &fImage));
    if (result != VK_SUCCESS) {
        return false;
    }

    VkMemoryRequirements requirements;
    GR_VK_CALL(vkGpu->vkInterface(), GetImageMemoryRequirements(vkGpu->device(),
                                                                fImage,
                                                                &requirements));

    uint32_t memoryTypeIndex = 0;
    VkPhysicalDeviceMemoryProperties phyDevMemProps;
    GR_VK_CALL(vkGpu->vkInterface(), GetPhysicalDeviceMemoryProperties(vkGpu->physicalDevice(),
                                                                       &phyDevMemProps));
    if (!find_memory_type_index(phyDevMemProps, requirements, &memoryTypeIndex)) {
        return false;
    }

    VkMemoryAllocateInfo allocInfo = {};
    allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
    allocInfo.allocationSize = requirements.size;
    allocInfo.memoryTypeIndex = memoryTypeIndex;

    SkASSERT(fImageMemory == VK_NULL_HANDLE);
    GR_VK_CALL_RESULT(vkGpu, result, AllocateMemory(vkGpu->device(), &allocInfo,
                                                    nullptr, &fImageMemory));
    if (result != VK_SUCCESS) {
        return false;
    }

    // Bind image memory.
    GR_VK_CALL_RESULT(vkGpu, result, BindImageMemory(vkGpu->device(),
                                                     fImage,
                                                     fImageMemory,
                                                     /*memoryOffset=*/0u));
    if (result != VK_SUCCESS) {
        return false;
    }

    void* mappedBuffer;
    GR_VK_CALL_RESULT(vkGpu, result, MapMemory(vkGpu->device(), fImageMemory, 0u,
                                               requirements.size, 0u, &mappedBuffer));
    if (result != VK_SUCCESS) {
        return false;
    }

    // Write Y channel.
    VkImageSubresource subresource;
    subresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT;
    subresource.mipLevel = 0;
    subresource.arrayLayer = 0;

    VkSubresourceLayout yLayout;
    GR_VK_CALL(vkGpu->vkInterface(), GetImageSubresourceLayout(vkGpu->device(), fImage,
                                                               &subresource, &yLayout));
    uint8_t* bufferData = reinterpret_cast<uint8_t*>(mappedBuffer) + yLayout.offset;
    for (size_t y = 0; y < height; ++y) {
        for (size_t x = 0; x < width; ++x) {
            bufferData[y * yLayout.rowPitch + x] = GetExpectedY(x, y, width, height);
        }
    }

    // Write UV channels.
    subresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT;
    VkSubresourceLayout uvLayout;
    GR_VK_CALL(vkGpu->vkInterface(), GetImageSubresourceLayout(vkGpu->device(), fImage,
                                                               &subresource, &uvLayout));
    bufferData = reinterpret_cast<uint8_t*>(mappedBuffer) + uvLayout.offset;
    for (size_t y = 0; y < height / 2; ++y) {
        for (size_t x = 0; x < width / 2; ++x) {
            auto [u, v] = GetExpectedUV(2*x, 2*y, width, height);
            bufferData[y * uvLayout.rowPitch + x * 2] = u;
            bufferData[y * uvLayout.rowPitch + x * 2 + 1] = v;
        }
    }

    VkMappedMemoryRange flushRange;
    flushRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
    flushRange.pNext = nullptr;
    flushRange.memory = fImageMemory;
    flushRange.offset = 0;
    flushRange.size = VK_WHOLE_SIZE;
    GR_VK_CALL_RESULT(vkGpu, result, FlushMappedMemoryRanges(vkGpu->device(), 1, &flushRange));
    if (result != VK_SUCCESS) {
        return false;
    }
    GR_VK_CALL(vkGpu->vkInterface(), UnmapMemory(vkGpu->device(), fImageMemory));

    // Wrap the image into SkImage.
    VkFormatProperties formatProperties;
    GR_VK_CALL(vkGpu->vkInterface(),
               GetPhysicalDeviceFormatProperties(vkGpu->physicalDevice(),
                                                 VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
                                                 &formatProperties));
    SkDEBUGCODE(auto linFlags = formatProperties.linearTilingFeatures;)
    SkASSERT((linFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) &&
             (linFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) &&
             (linFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT) &&
             (linFlags & VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT));

    skgpu::VulkanYcbcrConversionInfo ycbcrInfo(vkImageInfo.format,
                                               VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709,
                                               VK_SAMPLER_YCBCR_RANGE_ITU_NARROW,
                                               VK_CHROMA_LOCATION_COSITED_EVEN,
                                               VK_CHROMA_LOCATION_COSITED_EVEN,
                                               VK_FILTER_LINEAR,
                                               /*forceExplicitReconstruction=*/false,
                                               /*components=*/{},
                                               formatProperties.linearTilingFeatures);
    skgpu::VulkanAlloc alloc;
    alloc.fMemory = fImageMemory;
    alloc.fOffset = 0;
    alloc.fSize = requirements.size;

    GrVkImageInfo imageInfo = {fImage,
                               alloc,
                               VK_IMAGE_TILING_LINEAR,
                               VK_IMAGE_LAYOUT_PREINITIALIZED,
                               vkImageInfo.format,
                               vkImageInfo.usage,
                               1 /* sample count */,
                               1 /* levelCount */,
                               VK_QUEUE_FAMILY_IGNORED,
                               GrProtected::kNo,
                               ycbcrInfo};

    fGrTexture = GrBackendTextures::MakeVk(width, height, imageInfo);
    return true;
}

GrVkGpu* VkYcbcrSamplerHelper::vkGpu() {
    return fDContext ? (GrVkGpu*) fDContext->priv().getGpu() : nullptr;
}

VkYcbcrSamplerHelper::VkYcbcrSamplerHelper(GrDirectContext* dContext) : fDContext(dContext) {
    SkASSERT_RELEASE(dContext->backend() == GrBackendApi::kVulkan);
}
#endif  // SK_GANESH

VkYcbcrSamplerHelper::~VkYcbcrSamplerHelper() {
#ifdef SK_GRAPHITE
    if (fSharedCtxt) {
        if (fImage != VK_NULL_HANDLE) {
            VULKAN_CALL(fSharedCtxt->interface(),
                        DestroyImage(fSharedCtxt->device(), fImage, nullptr));
            fImage = VK_NULL_HANDLE;
        }
        if (fImageMemory != VK_NULL_HANDLE) {
            VULKAN_CALL(fSharedCtxt->interface(),
                        FreeMemory(fSharedCtxt->device(), fImageMemory, nullptr));
            fImageMemory = VK_NULL_HANDLE;
        }
    }
#endif // SK_GRAPHITE
#if defined (SK_GANESH)
    if (GrVkGpu* vkGpu = this->vkGpu()) {
        if (fImage != VK_NULL_HANDLE) {
            GR_VK_CALL(vkGpu->vkInterface(), DestroyImage(vkGpu->device(), fImage, nullptr));
            fImage = VK_NULL_HANDLE;
        }
        if (fImageMemory != VK_NULL_HANDLE) {
            GR_VK_CALL(vkGpu->vkInterface(), FreeMemory(vkGpu->device(), fImageMemory, nullptr));
            fImageMemory = VK_NULL_HANDLE;
        }
    }
#endif
}

bool VkYcbcrSamplerHelper::isYCbCrSupported() {
    VkFormatProperties formatProperties;
#ifdef SK_GRAPHITE
    if (fSharedCtxt) {
        if (!fSharedCtxt->vulkanCaps().supportsYcbcrConversion()) {
            return false;
        }

        SkASSERT(fSharedCtxt->physDevice() != VK_NULL_HANDLE);
        VULKAN_CALL(fSharedCtxt->interface(),
                    GetPhysicalDeviceFormatProperties(fSharedCtxt->physDevice(),
                                                      VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
                                                      &formatProperties));
    }
#endif
#if defined(SK_GANESH)
    if (GrVkGpu* vkGpu = this->vkGpu()) {
        if (!vkGpu->vkCaps().supportsYcbcrConversion()) {
            return false;
        }

        GR_VK_CALL(vkGpu->vkInterface(),
                GetPhysicalDeviceFormatProperties(vkGpu->physicalDevice(),
                                                    VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
                                                    &formatProperties));
    }
#endif  // SK_GANESH

    // The createBackendTexture call (which is the point of this helper class) requires linear
    // support for VK_FORMAT_G8_B8R8_2PLANE_420_UNORM including sampling and cosited chroma.
    // Verify that the image format is supported.
    auto linFlags = formatProperties.linearTilingFeatures;
    if (!(linFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) ||
        !(linFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) ||
        !(linFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT) ||
        !(linFlags & VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT)) {
        // VK_FORMAT_G8_B8R8_2PLANE_420_UNORM is not supported
        return false;
    }
    return true;
}
#endif // SK_VULKAN
