blob: 1465d091f02070882bc767e1ee063f9abcc6d3fe [file] [log] [blame]
Greg Daniel7e000222018-12-03 10:08:21 -05001/*
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
12GrVkSamplerYcbcrConversion* 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
Ethan Nicholas8e265a72018-12-12 16:22:40 -050071void GrVkSamplerYcbcrConversion::freeGPUData(GrVkGpu* gpu) const {
Greg Daniel7e000222018-12-03 10:08:21 -050072 SkASSERT(fYcbcrConversion);
73 GR_VK_CALL(gpu->vkInterface(), DestroySamplerYcbcrConversion(gpu->device(), fYcbcrConversion,
74 nullptr));
75}
76
77GrVkSamplerYcbcrConversion::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