Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
sampler_vk.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
10
11namespace impeller {
12
13static vk::UniqueSampler CreateSampler(
14 const vk::Device& device,
15 const SamplerDescriptor& desc,
16 const std::shared_ptr<YUVConversionVK>& yuv_conversion) {
17 const auto mip_map = ToVKSamplerMipmapMode(desc.mip_filter);
18
19 const auto min_filter = ToVKSamplerMinMagFilter(desc.min_filter);
20 const auto mag_filter = ToVKSamplerMinMagFilter(desc.mag_filter);
21
22 const auto address_mode_u = ToVKSamplerAddressMode(desc.width_address_mode);
23 const auto address_mode_v = ToVKSamplerAddressMode(desc.height_address_mode);
24 const auto address_mode_w = ToVKSamplerAddressMode(desc.depth_address_mode);
25
26 vk::StructureChain<vk::SamplerCreateInfo,
27 // For VK_KHR_sampler_ycbcr_conversion
28 vk::SamplerYcbcrConversionInfo>
29 sampler_chain;
30
31 auto& sampler_info = sampler_chain.get();
32
33 sampler_info.magFilter = mag_filter;
34 sampler_info.minFilter = min_filter;
35 sampler_info.addressModeU = address_mode_u;
36 sampler_info.addressModeV = address_mode_v;
37 sampler_info.addressModeW = address_mode_w;
38 sampler_info.borderColor = vk::BorderColor::eFloatTransparentBlack;
39 sampler_info.mipmapMode = mip_map;
40 sampler_info.maxLod = VK_LOD_CLAMP_NONE;
41
42 if (yuv_conversion && yuv_conversion->IsValid()) {
43 sampler_chain.get<vk::SamplerYcbcrConversionInfo>().conversion =
44 yuv_conversion->GetConversion();
45
46 //
47 // TL;DR: When using YUV conversion, our samplers are somewhat hobbled and
48 // not all options configurable in Impeller (especially the linear
49 // filtering which is by far the most used form of filtering) can be
50 // supported. Switch to safe defaults.
51 //
52 // Spec: If sampler Y'CBCR conversion is enabled and the potential format
53 // features of the sampler Y'CBCR conversion do not support or enable
54 // separate reconstruction filters, minFilter and magFilter must be equal to
55 // the sampler Y'CBCR conversion's chromaFilter.
56 //
57 // Thing is, we don't enable separate reconstruction filters. By the time we
58 // are here, we also don't have access to the descriptor used to create this
59 // conversion. So we don't yet know what the chromaFilter is. But eNearest
60 // is a safe bet since the `AndroidHardwareBufferTextureSourceVK` defaults
61 // to that safe value. So just use that.
62 //
63 // See the validation VUID-VkSamplerCreateInfo-minFilter-01645 for more.
64 //
65 sampler_info.magFilter = vk::Filter::eNearest;
66 sampler_info.minFilter = vk::Filter::eNearest;
67
68 // Spec: If sampler Y′CBCR conversion is enabled, addressModeU,
69 // addressModeV, and addressModeW must be
70 // VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, anisotropyEnable must be VK_FALSE,
71 // and unnormalizedCoordinates must be VK_FALSE.
72 //
73 // See the validation VUID-VkSamplerCreateInfo-addressModeU-01646 for more.
74 //
75 sampler_info.addressModeU = vk::SamplerAddressMode::eClampToEdge;
76 sampler_info.addressModeV = vk::SamplerAddressMode::eClampToEdge;
77 sampler_info.addressModeW = vk::SamplerAddressMode::eClampToEdge;
78 sampler_info.anisotropyEnable = false;
79 sampler_info.unnormalizedCoordinates = false;
80 } else {
81 sampler_chain.unlink<vk::SamplerYcbcrConversionInfo>();
82 }
83
84 auto sampler = device.createSamplerUnique(sampler_chain.get());
85 if (sampler.result != vk::Result::eSuccess) {
86 VALIDATION_LOG << "Could not create sampler: "
87 << vk::to_string(sampler.result);
88 return {};
89 }
90
91 if (!desc.label.empty()) {
92 ContextVK::SetDebugName(device, sampler.value.get(), desc.label.c_str());
93 }
94
95 return std::move(sampler.value);
96}
97
98SamplerVK::SamplerVK(const vk::Device& device,
100 std::shared_ptr<YUVConversionVK> yuv_conversion)
101 : Sampler(std::move(desc)),
102 device_(device),
103 sampler_(MakeSharedVK<vk::Sampler>(
104 CreateSampler(device, desc_, yuv_conversion))),
105 yuv_conversion_(std::move(yuv_conversion)) {
106 is_valid_ = sampler_ && !!sampler_->Get();
107}
108
109SamplerVK::~SamplerVK() = default;
110
111vk::Sampler SamplerVK::GetSampler() const {
112 return *sampler_;
113}
114
115std::shared_ptr<SamplerVK> SamplerVK::CreateVariantForConversion(
116 std::shared_ptr<YUVConversionVK> conversion) const {
117 if (!conversion || !is_valid_) {
118 return nullptr;
119 }
120 return std::make_shared<SamplerVK>(device_, desc_, std::move(conversion));
121}
122
123const std::shared_ptr<YUVConversionVK>& SamplerVK::GetYUVConversion() const {
124 return yuv_conversion_;
125}
126
127} // namespace impeller
bool SetDebugName(T handle, std::string_view label) const
Definition context_vk.h:108
vk::Sampler GetSampler() const
~SamplerVK() override
SamplerVK(const vk::Device &device, SamplerDescriptor desc, std::shared_ptr< YUVConversionVK > yuv_conversion={})
Definition sampler_vk.cc:98
std::shared_ptr< SamplerVK > CreateVariantForConversion(std::shared_ptr< YUVConversionVK > conversion) const
const std::shared_ptr< YUVConversionVK > & GetYUVConversion() const
SamplerDescriptor desc_
Definition sampler.h:22
VkDevice device
Definition main.cc:53
constexpr vk::SamplerAddressMode ToVKSamplerAddressMode(SamplerAddressMode mode)
Definition formats_vk.h:236
constexpr vk::SamplerMipmapMode ToVKSamplerMipmapMode(MipFilter filter)
Definition formats_vk.h:225
constexpr vk::Filter ToVKSamplerMinMagFilter(MinMagFilter filter)
Definition formats_vk.h:214
auto MakeSharedVK(vk::UniqueHandle< T, VULKAN_HPP_DEFAULT_DISPATCHER_TYPE > handle)
static vk::UniqueSampler CreateSampler(const vk::Device &device, const SamplerDescriptor &desc, const std::shared_ptr< YUVConversionVK > &yuv_conversion)
Definition sampler_vk.cc:13
Definition ref_ptr.h:256
#define VALIDATION_LOG
Definition validation.h:73
#define VK_LOD_CLAMP_NONE