xref: /aosp_15_r20/external/skia/src/gpu/ganesh/vk/GrVkSamplerYcbcrConversion.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2018 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 
8 #include "src/gpu/ganesh/vk/GrVkSamplerYcbcrConversion.h"
9 
10 #include "include/gpu/vk/VulkanTypes.h"
11 #include "include/private/base/SkAssert.h"
12 #include "src/gpu/ganesh/vk/GrVkCaps.h"
13 #include "src/gpu/ganesh/vk/GrVkGpu.h"
14 #include "src/gpu/ganesh/vk/GrVkUtil.h"
15 #include "src/gpu/vk/VulkanUtilsPriv.h"
16 
Create(GrVkGpu * gpu,const skgpu::VulkanYcbcrConversionInfo & info)17 GrVkSamplerYcbcrConversion* GrVkSamplerYcbcrConversion::Create(
18         GrVkGpu* gpu, const skgpu::VulkanYcbcrConversionInfo& info) {
19     if (!gpu->vkCaps().supportsYcbcrConversion()) {
20         return nullptr;
21     }
22 
23     VkSamplerYcbcrConversionCreateInfo ycbcrCreateInfo;
24     skgpu::SetupSamplerYcbcrConversionInfo(&ycbcrCreateInfo, info);
25 
26 #ifdef SK_BUILD_FOR_ANDROID
27     VkExternalFormatANDROID externalFormat;
28     if (info.fExternalFormat) {
29         // Format must not be specified for external images.
30         SkASSERT(info.fFormat == VK_FORMAT_UNDEFINED);
31         externalFormat.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID;
32         externalFormat.pNext = nullptr;
33         externalFormat.externalFormat = info.fExternalFormat;
34         SkASSERT(ycbcrCreateInfo.pNext == nullptr);
35         ycbcrCreateInfo.pNext = &externalFormat;
36     }
37 #else
38     // External images are supported only on Android.
39     SkASSERT(!info.fExternalFormat);
40 #endif
41 
42     if (!info.fExternalFormat) {
43         SkASSERT(info.fFormat != VK_FORMAT_UNDEFINED);
44     }
45 
46     VkSamplerYcbcrConversion conversion;
47     VkResult result;
48     GR_VK_CALL_RESULT(gpu, result, CreateSamplerYcbcrConversion(gpu->device(), &ycbcrCreateInfo,
49                                                                 nullptr, &conversion));
50     if (result != VK_SUCCESS) {
51         return nullptr;
52     }
53 
54     return new GrVkSamplerYcbcrConversion(gpu, conversion, GenerateKey(info));
55 }
56 
freeGPUData() const57 void GrVkSamplerYcbcrConversion::freeGPUData() const {
58     SkASSERT(fYcbcrConversion);
59     GR_VK_CALL(fGpu->vkInterface(), DestroySamplerYcbcrConversion(fGpu->device(),
60                                                                   fYcbcrConversion, nullptr));
61 }
62 
GenerateKey(const skgpu::VulkanYcbcrConversionInfo & ycbcrInfo)63 GrVkSamplerYcbcrConversion::Key GrVkSamplerYcbcrConversion::GenerateKey(
64         const skgpu::VulkanYcbcrConversionInfo& ycbcrInfo) {
65     SkASSERT(static_cast<int>(ycbcrInfo.fYcbcrModel <= 7));
66     static const int kRangeShift = 3;
67     SkASSERT(static_cast<int>(ycbcrInfo.fYcbcrRange) <= 1);
68     static const int kXChromaOffsetShift = kRangeShift + 1;
69     SkASSERT(static_cast<int>(ycbcrInfo.fXChromaOffset) <= 1);
70     static const int kYChromaOffsetShift = kXChromaOffsetShift + 1;
71     SkASSERT(static_cast<int>(ycbcrInfo.fXChromaOffset) <= 1);
72     static const int kChromaFilterShift = kYChromaOffsetShift + 1;
73     SkASSERT(static_cast<int>(ycbcrInfo.fChromaFilter) <= 1);
74     static const int kReconShift = kChromaFilterShift + 1;
75     SkASSERT(static_cast<int>(ycbcrInfo.fForceExplicitReconstruction) <= 1);
76     static const int kCompRShift = kReconShift + 1;
77     static const int kCompGShift = kCompRShift + 3;
78     static const int kCompBShift = kCompGShift + 3;
79     static const int kCompAShift = kCompBShift + 3;
80     SkASSERT(static_cast<int>(ycbcrInfo.fComponents.r <= 6) &&
81              static_cast<int>(ycbcrInfo.fComponents.g <= 6) &&
82              static_cast<int>(ycbcrInfo.fComponents.b <= 6) &&
83              static_cast<int>(ycbcrInfo.fComponents.a <= 6));
84     static_assert(kCompAShift <= 17);
85 
86     uint32_t ycbcrKey = static_cast<uint32_t>(ycbcrInfo.fYcbcrModel);
87     ycbcrKey |= (static_cast<uint32_t>(ycbcrInfo.fYcbcrRange) << kRangeShift);
88     ycbcrKey |= (static_cast<uint32_t>(ycbcrInfo.fXChromaOffset) << kXChromaOffsetShift);
89     ycbcrKey |= (static_cast<uint32_t>(ycbcrInfo.fYChromaOffset) << kYChromaOffsetShift);
90     ycbcrKey |= (static_cast<uint32_t>(ycbcrInfo.fChromaFilter) << kChromaFilterShift);
91     ycbcrKey |= (static_cast<uint32_t>(ycbcrInfo.fForceExplicitReconstruction) << kReconShift);
92     ycbcrKey |= (static_cast<uint32_t>(ycbcrInfo.fComponents.r) << kCompRShift);
93     ycbcrKey |= (static_cast<uint32_t>(ycbcrInfo.fComponents.g) << kCompGShift);
94     ycbcrKey |= (static_cast<uint32_t>(ycbcrInfo.fComponents.b) << kCompBShift);
95     ycbcrKey |= (static_cast<uint32_t>(ycbcrInfo.fComponents.a) << kCompAShift);
96 
97     return Key{ycbcrInfo.fFormat, ycbcrInfo.fExternalFormat, ycbcrKey};
98 }
99