// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "impeller/renderer/backend/vulkan/sampler_library_vk.h"

#include "impeller/renderer/backend/vulkan/formats_vk.h"
#include "impeller/renderer/backend/vulkan/sampler_vk.h"

namespace impeller {

SamplerLibraryVK::SamplerLibraryVK(vk::Device device) : device_(device) {}

SamplerLibraryVK::~SamplerLibraryVK() = default;

std::shared_ptr<const Sampler> SamplerLibraryVK::GetSampler(
    SamplerDescriptor desc) {
  auto found = samplers_.find(desc);
  if (found != samplers_.end()) {
    return found->second;
  }
  if (!device_) {
    return nullptr;
  }

  const auto mip_map = ToVKSamplerMipmapMode(desc.mip_filter);

  const auto min_filter = ToVKSamplerMinMagFilter(desc.min_filter);
  const auto mag_filter = ToVKSamplerMinMagFilter(desc.mag_filter);

  const auto address_mode_u = ToVKSamplerAddressMode(desc.width_address_mode);
  const auto address_mode_v = ToVKSamplerAddressMode(desc.height_address_mode);
  const auto address_mode_w = ToVKSamplerAddressMode(desc.depth_address_mode);

  const auto sampler_create_info = vk::SamplerCreateInfo()
                                       .setMagFilter(mag_filter)
                                       .setMinFilter(min_filter)
                                       .setAddressModeU(address_mode_u)
                                       .setAddressModeV(address_mode_v)
                                       .setAddressModeW(address_mode_w)
                                       .setMipmapMode(mip_map);

  auto res = device_.createSamplerUnique(sampler_create_info);
  if (res.result != vk::Result::eSuccess) {
    FML_LOG(ERROR) << "Failed to create sampler: " << vk::to_string(res.result);
    return nullptr;
  }

  auto sampler = std::make_shared<SamplerVK>(desc, std::move(res.value));

  if (!sampler->IsValid()) {
    return nullptr;
  }
  samplers_[desc] = sampler;
  return sampler;
}

}  // namespace impeller
