Flutter Engine
The Flutter Engine
VulkanYcbcrConversion.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2023 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
14
15namespace skgpu::graphite {
16
18 const VulkanSharedContext* context, const VulkanYcbcrConversionInfo& conversionInfo) {
19 if (!context->vulkanCaps().supportsYcbcrConversion()) {
20 return nullptr;
21 }
22
24 skgpu::SetupSamplerYcbcrConversionInfo(&ycbcrCreateInfo, conversionInfo);
25
26#ifdef SK_BUILD_FOR_ANDROID
27 VkExternalFormatANDROID externalFormat;
28 if (conversionInfo.fExternalFormat) {
29 // Format must not be specified for external images.
30 SkASSERT(conversionInfo.fFormat == VK_FORMAT_UNDEFINED);
32 externalFormat.pNext = nullptr;
33 externalFormat.externalFormat = conversionInfo.fExternalFormat;
34 SkASSERT(ycbcrCreateInfo.pNext == nullptr);
35 ycbcrCreateInfo.pNext = &externalFormat;
36 }
37#else
38 // External images are supported only on Android.
39 SkASSERT(!conversionInfo.fExternalFormat);
40#endif
41
42 if (!conversionInfo.fExternalFormat) {
43 SkASSERT(conversionInfo.fFormat != VK_FORMAT_UNDEFINED);
44 }
45
46 VkSamplerYcbcrConversion conversion;
48 VULKAN_CALL_RESULT(context,
49 result,
50 CreateSamplerYcbcrConversion(
51 context->device(), &ycbcrCreateInfo, nullptr, &conversion));
52 if (result != VK_SUCCESS) {
53 return nullptr;
54 }
55 return sk_sp<VulkanYcbcrConversion>(new VulkanYcbcrConversion(context, conversion));
56}
57
59 uint32_t nonFormatInfo,
60 uint64_t format) {
62
63 bool useExternalFormat = static_cast<bool>(
66
68 ycbcrCreateInfo.pNext = nullptr;
69 ycbcrCreateInfo.format = useExternalFormat ? VK_FORMAT_UNDEFINED
70 : static_cast<VkFormat>(format);
71
72 ycbcrCreateInfo.ycbcrModel = static_cast<VkSamplerYcbcrModelConversion>(
73 (nonFormatInfo & ycbcrPackaging::kYcbcrModelMask) >>
75 ycbcrCreateInfo.ycbcrRange = static_cast<VkSamplerYcbcrRange>(
76 (nonFormatInfo & ycbcrPackaging::kYcbcrRangeMask) >>
78 ycbcrCreateInfo.components = {
79 static_cast<VkComponentSwizzle>(
80 (nonFormatInfo & ycbcrPackaging::kComponentRMask) >>
82 static_cast<VkComponentSwizzle>(
83 (nonFormatInfo & ycbcrPackaging::kComponentGMask) >>
85 static_cast<VkComponentSwizzle>(
86 (nonFormatInfo & ycbcrPackaging::kComponentBMask) >>
88 static_cast<VkComponentSwizzle>(
89 (nonFormatInfo & ycbcrPackaging::kComponentAMask) >>
91 ycbcrCreateInfo.xChromaOffset = static_cast<VkChromaLocation>(
92 (nonFormatInfo & ycbcrPackaging::kXChromaOffsetMask) >>
94 ycbcrCreateInfo.yChromaOffset = static_cast<VkChromaLocation>(
95 (nonFormatInfo & ycbcrPackaging::kYChromaOffsetMask) >>
97 ycbcrCreateInfo.chromaFilter = static_cast<VkFilter>(
98 (nonFormatInfo & ycbcrPackaging::kChromaFilterMask) >>
100 ycbcrCreateInfo.forceExplicitReconstruction = static_cast<VkBool32>(
101 (nonFormatInfo & ycbcrPackaging::kForceExplicitReconMask) >>
103
104#ifdef SK_BUILD_FOR_ANDROID
105 VkExternalFormatANDROID externalFormat;
106 if (useExternalFormat) {
108 externalFormat.pNext = nullptr;
109 externalFormat.externalFormat = format;
110 SkASSERT(ycbcrCreateInfo.pNext == nullptr);
111 ycbcrCreateInfo.pNext = &externalFormat;
112 }
113#endif
114
115 VkSamplerYcbcrConversion conversion;
117 VULKAN_CALL_RESULT(context,
118 result,
119 CreateSamplerYcbcrConversion(
120 context->device(), &ycbcrCreateInfo, nullptr, &conversion));
121 if (result != VK_SUCCESS) {
122 return nullptr;
123 }
124 return sk_sp<VulkanYcbcrConversion>(new VulkanYcbcrConversion(context, conversion));
125}
126
127namespace {
128// Define this anonymous helper to get a static resource type for YCbCr conversions regardless of
129// which method is used to create it (from VulkanYcbcrConversionInfo or from SamplerDesc)
130ResourceType conversion_rsrc_type() {
131 static const ResourceType conversionType = GraphiteResourceKey::GenerateResourceType();
132 return conversionType;
133}
134}
136 const VulkanSharedContext* context, const VulkanYcbcrConversionInfo& info) {
137 bool useExternalFormat = info.fFormat == VK_FORMAT_UNDEFINED;
140 conversion_rsrc_type(),
143 int i = 0;
145 if (useExternalFormat) {
146 builder[i++] = (uint32_t)info.fExternalFormat;
147 builder[i++] = (uint32_t)(info.fExternalFormat >> 32);
148 } else {
149 builder[i++] = (uint32_t)info.fFormat;
150 }
152
153 builder.finish();
154 return key;
155}
156
159 const SkSpan<const uint32_t>& samplerData = samplerDesc.asSpan();
160 GraphiteResourceKey::Builder builder(&key, conversion_rsrc_type(), samplerData.size(),
162
163 // The first index of sampler data (sampler desc value) includes non-ycbcr information
164 // that needs to be shifted past in order to isolate the ycbcr information for this key.
166 for (size_t i = 1; i < samplerData.size(); i++) {
167 builder[i] = samplerData[i];
168 }
169
170 builder.finish();
171 return key;
172}
173
174VulkanYcbcrConversion::VulkanYcbcrConversion(const VulkanSharedContext* context,
175 VkSamplerYcbcrConversion ycbcrConversion)
176 : Resource(context,
178 skgpu::Budgeted::kYes, // Shareable, so must be budgeted
179 /*gpuMemorySize=*/0)
180 , fYcbcrConversion (ycbcrConversion) {}
181
182void VulkanYcbcrConversion::freeGpuData() {
183 auto sharedContext = static_cast<const VulkanSharedContext*>(this->sharedContext());
184 SkASSERT(fYcbcrConversion != VK_NULL_HANDLE);
185 VULKAN_CALL(sharedContext->interface(),
186 DestroySamplerYcbcrConversion(sharedContext->device(), fYcbcrConversion, nullptr));
187}
188
189} // namespace skgpu::graphite
190
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
#define SkASSERT(cond)
Definition: SkAssert.h:116
@ kYes
Do pre-clip the geometry before applying the (perspective) matrix.
#define VULKAN_CALL(IFACE, X)
#define VULKAN_CALL_RESULT(SHARED_CONTEXT, RESULT, X)
constexpr size_t size() const
Definition: SkSpan_impl.h:95
const GraphiteResourceKey & key() const
Definition: Resource.h:156
const SharedContext * sharedContext() const
Definition: Resource.h:189
bool supportsYcbcrConversion() const
Definition: VulkanCaps.h:88
const VulkanCaps & vulkanCaps() const
static GraphiteResourceKey GetKeyFromSamplerDesc(const SamplerDesc &samplerDesc)
static sk_sp< VulkanYcbcrConversion > Make(const VulkanSharedContext *, const VulkanYcbcrConversionInfo &)
static GraphiteResourceKey MakeYcbcrConversionKey(const VulkanSharedContext *, const VulkanYcbcrConversionInfo &)
GAsyncResult * result
uint32_t uint32_t * format
static constexpr uint32_t kYChromaOffsetMask
static constexpr uint32_t kComponentAMask
static constexpr uint32_t kYcbcrRangeMask
static constexpr uint32_t kComponentGMask
static constexpr uint32_t kXChromaOffsetMask
int numInt32sNeeded(const VulkanYcbcrConversionInfo &conversionInfo)
static constexpr uint32_t kUseExternalFormatMask
static constexpr uint32_t kYcbcrModelMask
static constexpr int kUsesExternalFormatShift
static constexpr int kForceExplicitReconShift
static constexpr uint32_t kChromaFilterMask
uint32_t nonFormatInfoAsUInt32(const VulkanYcbcrConversionInfo &conversionInfo)
static constexpr uint32_t kForceExplicitReconMask
static constexpr uint32_t kComponentRMask
static constexpr uint32_t kComponentBMask
uint32_t ResourceType
Definition: GpuTools.h:21
Budgeted
Definition: GpuTypes.h:35
void SetupSamplerYcbcrConversionInfo(VkSamplerYcbcrConversionCreateInfo *outInfo, const VulkanYcbcrConversionInfo &conversionInfo)
VkStructureType sType
VkSamplerYcbcrModelConversion ycbcrModel
Definition: vulkan_core.h:5426
static constexpr int kImmutableSamplerInfoShift
SkSpan< const uint32_t > asSpan() const
VkSamplerYcbcrModelConversion
Definition: vulkan_core.h:4945
VkChromaLocation
Definition: vulkan_core.h:4967
VkComponentSwizzle
Definition: vulkan_core.h:1818
VkSamplerYcbcrRange
Definition: vulkan_core.h:4959
VkFilter
Definition: vulkan_core.h:2100
VkResult
Definition: vulkan_core.h:140
@ VK_SUCCESS
Definition: vulkan_core.h:141
#define VK_NULL_HANDLE
Definition: vulkan_core.h:46
VkFormat
Definition: vulkan_core.h:1458
@ VK_FORMAT_UNDEFINED
Definition: vulkan_core.h:1459
uint32_t VkBool32
Definition: vulkan_core.h:94
@ VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO
Definition: vulkan_core.h:292
@ VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID
Definition: vulkan_core.h:647