/*
 * Copyright 2020 Google Inc.
 *
 * 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/ganesh/GrDirectContext.h"
#include "include/gpu/ganesh/vk/GrVkBackendSurface.h"
#include "include/gpu/vk/VulkanTypes.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/vk/GrVkGpu.h"
#include "src/gpu/ganesh/vk/GrVkUtil.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

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_UNDEFINED;
}

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;
    }

    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));

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

    // 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,
                                                  /*externalFormat=*/0,
                                                  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,
                                                  false,
                                                  formatProperties.linearTilingFeatures};
    skgpu::VulkanAlloc alloc;
    alloc.fMemory = fImageMemory;
    alloc.fOffset = 0;
    alloc.fSize = requirements.size;

    skgpu::graphite::VulkanTextureInfo imageInfo = {
            static_cast<uint32_t>(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_UNDEFINED,
                                                            /*queueFamilyIndex=*/0,
                                                            fImage,
                                                            alloc);
    return true;
}
#endif // SK_GRAPHITE

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;
    }

    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));

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

    // 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,
                                                  /*externalFormat=*/0,
                                                  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,
                                                  false,
                                                  formatProperties.linearTilingFeatures,
                                                  /*fComponents=*/{}};
    skgpu::VulkanAlloc alloc;
    alloc.fMemory = fImageMemory;
    alloc.fOffset = 0;
    alloc.fSize = requirements.size;

    GrVkImageInfo imageInfo = {fImage,
                               alloc,
                               VK_IMAGE_TILING_LINEAR,
                               VK_IMAGE_LAYOUT_UNDEFINED,
                               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 (GrVkGpu*) fDContext->priv().getGpu();
}

VkYcbcrSamplerHelper::VkYcbcrSamplerHelper(GrDirectContext* dContext) : fDContext(dContext) {
    SkASSERT_RELEASE(dContext->backend() == GrBackendApi::kVulkan);
#if defined(SK_GRAPHITE)
    fSharedCtxt = nullptr;
#endif
}

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;
        }
    } else
#endif // SK_GRAPHITE
    {
        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;
        }
    }
}

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));
    } else
#endif
    {
        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));
    }

    // 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
