• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "GrVkSamplerYcbcrConversion.h"
9 
10 #include "GrVkGpu.h"
11 
Create(const GrVkGpu * gpu,const GrVkYcbcrConversionInfo & info)12 GrVkSamplerYcbcrConversion* GrVkSamplerYcbcrConversion::Create(
13         const GrVkGpu* gpu, const GrVkYcbcrConversionInfo& info) {
14     if (!gpu->vkCaps().supportsYcbcrConversion()) {
15         return nullptr;
16     }
17     // We only support creating ycbcr conversion for external formats;
18     SkASSERT(info.fExternalFormat);
19 
20 #ifdef SK_DEBUG
21     const VkFormatFeatureFlags& featureFlags = info.fExternalFormatFeatures;
22     if (info.fXChromaOffset == VK_CHROMA_LOCATION_MIDPOINT ||
23         info.fYChromaOffset == VK_CHROMA_LOCATION_MIDPOINT) {
24         SkASSERT(featureFlags & VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT);
25     }
26     if (info.fXChromaOffset == VK_CHROMA_LOCATION_COSITED_EVEN ||
27         info.fYChromaOffset == VK_CHROMA_LOCATION_COSITED_EVEN) {
28         SkASSERT(featureFlags & VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT);
29     }
30     if (info.fChromaFilter == VK_FILTER_LINEAR) {
31         SkASSERT(featureFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT);
32     }
33     if (info.fForceExplicitReconstruction) {
34         SkASSERT(featureFlags &
35                  VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT);
36     }
37 #endif
38 
39 #ifdef SK_BUILD_FOR_ANDROID
40     VkExternalFormatANDROID externalFormat;
41     externalFormat.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID;
42     externalFormat.pNext = nullptr;
43     externalFormat.externalFormat = info.fExternalFormat;
44 
45     VkSamplerYcbcrConversionCreateInfo ycbcrCreateInfo;
46     memset(&ycbcrCreateInfo, 0, sizeof(VkSamplerYcbcrConversionCreateInfo));
47     ycbcrCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO;
48     ycbcrCreateInfo.pNext = &externalFormat;
49     ycbcrCreateInfo.format = VK_FORMAT_UNDEFINED;
50     ycbcrCreateInfo.ycbcrModel = info.fYcbcrModel;
51     ycbcrCreateInfo.ycbcrRange = info.fYcbcrRange;
52     // Componets is ignored for external format conversions;
53     // ycbcrCreateInfo.components = {0, 0, 0, 0};
54     ycbcrCreateInfo.xChromaOffset = info.fXChromaOffset;
55     ycbcrCreateInfo.yChromaOffset = info.fYChromaOffset;
56     ycbcrCreateInfo.chromaFilter = info.fChromaFilter;
57     ycbcrCreateInfo.forceExplicitReconstruction = info.fForceExplicitReconstruction;
58 
59     VkSamplerYcbcrConversion conversion;
60     GR_VK_CALL(gpu->vkInterface(), CreateSamplerYcbcrConversion(gpu->device(), &ycbcrCreateInfo,
61                                                                 nullptr, &conversion));
62     if (conversion == VK_NULL_HANDLE) {
63         return nullptr;
64     }
65     return new GrVkSamplerYcbcrConversion(conversion, GenerateKey(info));
66 #else
67     return nullptr;
68 #endif
69 }
70 
freeGPUData(GrVkGpu * gpu) const71 void GrVkSamplerYcbcrConversion::freeGPUData(GrVkGpu* gpu) const {
72     SkASSERT(fYcbcrConversion);
73     GR_VK_CALL(gpu->vkInterface(), DestroySamplerYcbcrConversion(gpu->device(), fYcbcrConversion,
74                                                                  nullptr));
75 }
76 
GenerateKey(const GrVkYcbcrConversionInfo & ycbcrInfo)77 GrVkSamplerYcbcrConversion::Key GrVkSamplerYcbcrConversion::GenerateKey(
78         const GrVkYcbcrConversionInfo& ycbcrInfo) {
79     SkASSERT(static_cast<int>(ycbcrInfo.fYcbcrModel <= 7));
80     static const int kRangeShift = 3;
81     SkASSERT(static_cast<int>(ycbcrInfo.fYcbcrRange) <= 1);
82     static const int kXChromaOffsetShift = kRangeShift + 1;
83     SkASSERT(static_cast<int>(ycbcrInfo.fXChromaOffset) <= 1);
84     static const int kYChromaOffsetShift = kXChromaOffsetShift + 1;
85     SkASSERT(static_cast<int>(ycbcrInfo.fXChromaOffset) <= 1);
86     static const int kChromaFilterShift = kYChromaOffsetShift + 1;
87     SkASSERT(static_cast<int>(ycbcrInfo.fChromaFilter) <= 1);
88     static const int kReconShift = kChromaFilterShift + 1;
89     SkASSERT(static_cast<int>(ycbcrInfo.fForceExplicitReconstruction) <= 1);
90     GR_STATIC_ASSERT(kReconShift <= 7);
91 
92     uint8_t ycbcrKey = static_cast<uint8_t>(ycbcrInfo.fYcbcrModel);
93     ycbcrKey |= (static_cast<uint8_t>(ycbcrInfo.fYcbcrRange) << kRangeShift);
94     ycbcrKey |= (static_cast<uint8_t>(ycbcrInfo.fXChromaOffset) << kXChromaOffsetShift);
95     ycbcrKey |= (static_cast<uint8_t>(ycbcrInfo.fYChromaOffset) << kYChromaOffsetShift);
96     ycbcrKey |= (static_cast<uint8_t>(ycbcrInfo.fChromaFilter) << kChromaFilterShift);
97     ycbcrKey |= (static_cast<uint8_t>(ycbcrInfo.fForceExplicitReconstruction) << kReconShift);
98 
99     return {ycbcrInfo.fExternalFormat, ycbcrKey};
100 }
101 
102