blob: 7c20b454505c2d9068775fee46a9cd8402f63b55 [file] [log] [blame] [edit]
// Copyright 2019 The Fuchsia 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 "src/ui/lib/escher/vk/sampler.h"
#include "src/ui/lib/escher/impl/vulkan_utils.h"
#include "src/ui/lib/escher/resources/resource_recycler.h"
#include "src/ui/lib/escher/util/image_utils.h"
namespace escher {
const ResourceTypeInfo Sampler::kTypeInfo("Sampler", ResourceType::kResource,
ResourceType::kSampler);
Sampler::Sampler(ResourceRecycler* resource_recycler, vk::Format format, vk::Filter filter,
bool use_unnormalized_coordinates)
: Resource(resource_recycler), is_immutable_(false) {
auto device = resource_recycler->vulkan_context().device;
// TODO(SCN-1403): eG8B8R82Plane420Unorm/eG8B8G8R8422Unorm is not enough to assume NV12, but
// they're currently the only formats we support at the sampler level.
if (image_utils::IsYuvFormat(format)) {
FXL_DCHECK(resource_recycler->caps().allow_ycbcr);
vk::SamplerYcbcrConversionCreateInfo ycbcr_create_info;
ycbcr_create_info.pNext = nullptr;
ycbcr_create_info.format = format;
ycbcr_create_info.ycbcrModel = vk::SamplerYcbcrModelConversion::eYcbcr709;
ycbcr_create_info.ycbcrRange = vk::SamplerYcbcrRange::eItuNarrow;
ycbcr_create_info.components = {
VK_COMPONENT_SWIZZLE_IDENTITY, // R
VK_COMPONENT_SWIZZLE_IDENTITY, // G
VK_COMPONENT_SWIZZLE_IDENTITY, // B
VK_COMPONENT_SWIZZLE_IDENTITY, // A
};
ycbcr_create_info.xChromaOffset = vk::ChromaLocation::eCositedEven;
ycbcr_create_info.yChromaOffset = vk::ChromaLocation::eCositedEven;
ycbcr_create_info.chromaFilter = filter;
ycbcr_create_info.forceExplicitReconstruction = VK_FALSE;
ycbcr_conversion_ = ESCHER_CHECKED_VK_RESULT(device.createSamplerYcbcrConversionKHR(
ycbcr_create_info, nullptr, resource_recycler->vulkan_context().loader));
is_immutable_ = true;
}
vk::SamplerCreateInfo sampler_info;
sampler_info.pNext = GetExtensionData();
sampler_info.magFilter = filter;
sampler_info.minFilter = filter;
sampler_info.anisotropyEnable = false;
sampler_info.maxAnisotropy = 1.0;
sampler_info.unnormalizedCoordinates = use_unnormalized_coordinates;
sampler_info.compareEnable = VK_FALSE;
sampler_info.compareOp = vk::CompareOp::eAlways;
sampler_info.mipLodBias = 0.0f;
sampler_info.minLod = 0.0f;
sampler_info.maxLod = 0.0f;
if (use_unnormalized_coordinates) {
sampler_info.mipmapMode = vk::SamplerMipmapMode::eNearest;
} else {
sampler_info.mipmapMode = vk::SamplerMipmapMode::eLinear;
}
sampler_info.addressModeU = vk::SamplerAddressMode::eClampToEdge;
sampler_info.addressModeV = vk::SamplerAddressMode::eClampToEdge;
sampler_info.addressModeW = vk::SamplerAddressMode::eClampToEdge;
sampler_ = ESCHER_CHECKED_VK_RESULT(vk_device().createSampler(sampler_info));
}
Sampler::~Sampler() {
if (is_immutable_) {
vk_device().destroySamplerYcbcrConversionKHR(ycbcr_conversion_.conversion, nullptr,
vulkan_context().loader);
}
vk_device().destroySampler(sampler_);
}
} // namespace escher