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