| Flutter Impeller |

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
5 #include "impeller/renderer/backend/vulkan/sampler_vk.h"
6
7 #include "impeller/renderer/backend/vulkan/context_vk.h"
8 #include "impeller/renderer/backend/vulkan/formats_vk.h"
9 #include "impeller/renderer/backend/vulkan/yuv_conversion_vk.h"
10 #include "vulkan/vulkan_core.h"
11
12 namespace impeller {
13
14 static vk::UniqueSampler CreateSampler(
15 const vk::Device& device,
16 const SamplerDescriptor& desc,
17 const std::shared_ptr<YUVConversionVK>& yuv_conversion) {
18 const auto min_filter = ToVKSamplerMinMagFilter(desc.min_filter);
19 const auto mag_filter = ToVKSamplerMinMagFilter(desc.mag_filter);
20
21 const auto address_mode_u = ToVKSamplerAddressMode(desc.width_address_mode);
22 const auto address_mode_v = ToVKSamplerAddressMode(desc.height_address_mode);
23 const auto address_mode_w = ToVKSamplerAddressMode(desc.depth_address_mode);
24
25 vk::StructureChain<vk::SamplerCreateInfo,
26 // For VK_KHR_sampler_ycbcr_conversion
27 vk::SamplerYcbcrConversionInfo>
28 sampler_chain;
29
30 auto& sampler_info = sampler_chain.get();
31
32 sampler_info.magFilter = mag_filter;
33 sampler_info.minFilter = min_filter;
34 sampler_info.addressModeU = address_mode_u;
35 sampler_info.addressModeV = address_mode_v;
36 sampler_info.addressModeW = address_mode_w;
37 sampler_info.borderColor = vk::BorderColor::eFloatTransparentBlack;
38 sampler_info.maxLod = VK_LOD_CLAMP_NONE;
39
40 // https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkSamplerCreateInfo.html#_description
41 switch (desc.mip_filter) {
42 case MipFilter::kBase:
43 sampler_info.mipmapMode = vk::SamplerMipmapMode::eNearest;
44 sampler_info.minLod = sampler_info.maxLod = 0.0f;
45 break;
46 case MipFilter::kNearest:
47 sampler_info.mipmapMode = vk::SamplerMipmapMode::eNearest;
48 break;
49 case MipFilter::kLinear:
50 sampler_info.mipmapMode = vk::SamplerMipmapMode::eLinear;
51 break;
52 }
53
54 if (yuv_conversion && yuv_conversion->IsValid()) {
55 sampler_chain.get<vk::SamplerYcbcrConversionInfo>().conversion =
56 yuv_conversion->GetConversion();
57
58 // Spec: If sampler Y'CBCR conversion is enabled and the potential format
59 // features of the sampler Y'CBCR conversion do not support or enable
60 // separate reconstruction filters, minFilter and magFilter must be equal to
61 // the sampler Y'CBCR conversion's chromaFilter.
62 //
63 // We don't enable separate reconstruction filters. So, just do what the
64 // spec. says and use the conversions chromaFilter.
65 //
66 // See the validation VUID-VkSamplerCreateInfo-minFilter-01645 for more.
67 //
68 sampler_info.minFilter = sampler_info.magFilter =
69 yuv_conversion->GetDescriptor().get().chromaFilter;
70
71 // Spec: If sampler Y′CBCR conversion is enabled, addressModeU,
72 // addressModeV, and addressModeW must be
73 // VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, anisotropyEnable must be VK_FALSE,
74 // and unnormalizedCoordinates must be VK_FALSE.
75 //
76 // See the validation VUID-VkSamplerCreateInfo-addressModeU-01646 for more.
77 //
78 sampler_info.addressModeU = vk::SamplerAddressMode::eClampToEdge;
79 sampler_info.addressModeV = vk::SamplerAddressMode::eClampToEdge;
80 sampler_info.addressModeW = vk::SamplerAddressMode::eClampToEdge;
81 sampler_info.anisotropyEnable = false;
82 sampler_info.unnormalizedCoordinates = false;
83 } else {
84 sampler_chain.unlink<vk::SamplerYcbcrConversionInfo>();
85 }
86
87 auto sampler = device.createSamplerUnique(sampler_chain.get());
88 if (sampler.result != vk::Result::eSuccess) {
89 VALIDATION_LOG << "Could not create sampler: "
90 << vk::to_string(sampler.result);
91 return {};
92 }
93
94 if (!desc.label.empty()) {
95 ContextVK::SetDebugName(device, sampler.value.get(), desc.label.data());
96 }
97
98 return std::move(sampler.value);
99 }
100
101 SamplerVK::SamplerVK(const vk::Device& device,
102 const SamplerDescriptor& desc,
103 std::shared_ptr<YUVConversionVK> yuv_conversion)
104 : Sampler(desc),
105 device_(device),
106 sampler_(MakeSharedVK<vk::Sampler>(
107 CreateSampler(device, desc_, yuv_conversion))),
108 yuv_conversion_(std::move(yuv_conversion)) {
109 is_valid_ = sampler_ && !!sampler_->Get();
110 }
111
112 SamplerVK::~SamplerVK() = default;
113
114 vk::Sampler SamplerVK::GetSampler() const {
115 return *sampler_;
116 }
117
118 std::shared_ptr<SamplerVK> SamplerVK::CreateVariantForConversion(
119 std::shared_ptr<YUVConversionVK> conversion) const {
120 if (!conversion || !is_valid_) {
121 return nullptr;
122 }
123 return std::make_shared<SamplerVK>(device_, desc_, std::move(conversion));
124 }
125
126 const std::shared_ptr<YUVConversionVK>& SamplerVK::GetYUVConversion() const {
127 return yuv_conversion_;
128 }
129
130 } // namespace impeller
impeller::ContextVK::SetDebugName
bool SetDebugName(T handle, std::string_view label) const
Definition: context_vk.h:151
impeller::Sampler
Definition: sampler.h:12
impeller::Sampler::desc_
SamplerDescriptor desc_
Definition: sampler.h:19
impeller::SamplerVK::GetSampler
vk::Sampler GetSampler() const
Definition: sampler_vk.cc:114
impeller::SamplerVK::~SamplerVK
~SamplerVK() override
impeller::SamplerVK::SamplerVK
SamplerVK(const vk::Device &device, const SamplerDescriptor &, std::shared_ptr< YUVConversionVK > yuv_conversion={})
Definition: sampler_vk.cc:101
impeller::SamplerVK::CreateVariantForConversion
std::shared_ptr< SamplerVK > CreateVariantForConversion(std::shared_ptr< YUVConversionVK > conversion) const
Definition: sampler_vk.cc:118
impeller::SamplerVK::GetYUVConversion
const std::shared_ptr< YUVConversionVK > & GetYUVConversion() const
Definition: sampler_vk.cc:126
desc_
std::optional< PipelineDescriptor > desc_
Definition: content_context.cc:75
formats_vk.h
impeller
Definition: allocation.cc:12
impeller::ToVKSamplerAddressMode
constexpr vk::SamplerAddressMode ToVKSamplerAddressMode(SamplerAddressMode mode)
Definition: formats_vk.h:248
impeller::ToVKSamplerMinMagFilter
constexpr vk::Filter ToVKSamplerMinMagFilter(MinMagFilter filter)
Definition: formats_vk.h:225
impeller::MipFilter::kLinear
@ kLinear
Sample from the two nearest mip levels and linearly interpolate.
impeller::MipFilter::kBase
@ kBase
The texture is sampled as if it only had a single mipmap level.
impeller::MipFilter::kNearest
@ kNearest
The nearst mipmap level is selected.
impeller::MakeSharedVK
auto MakeSharedVK(vk::UniqueHandle< T, VULKAN_HPP_DEFAULT_DISPATCHER_TYPE > handle)
Definition: shared_object_vk.h:44
impeller::CreateSampler
static vk::UniqueSampler CreateSampler(const vk::Device &device, const SamplerDescriptor &desc, const std::shared_ptr< YUVConversionVK > &yuv_conversion)
Definition: sampler_vk.cc:14
std
Definition: comparable.h:95
context_vk.h
sampler_vk.h
impeller::SamplerDescriptor
Definition: sampler_descriptor.h:14
impeller::SamplerDescriptor::depth_address_mode
SamplerAddressMode depth_address_mode
Definition: sampler_descriptor.h:21
impeller::SamplerDescriptor::mip_filter
MipFilter mip_filter
Definition: sampler_descriptor.h:17
impeller::SamplerDescriptor::width_address_mode
SamplerAddressMode width_address_mode
Definition: sampler_descriptor.h:19
impeller::SamplerDescriptor::height_address_mode
SamplerAddressMode height_address_mode
Definition: sampler_descriptor.h:20
impeller::SamplerDescriptor::mag_filter
MinMagFilter mag_filter
Definition: sampler_descriptor.h:16
impeller::SamplerDescriptor::label
std::string_view label
Definition: sampler_descriptor.h:23
impeller::SamplerDescriptor::min_filter
MinMagFilter min_filter
Definition: sampler_descriptor.h:15
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:91
yuv_conversion_vk.h