1 /*
2 * Copyright 2024 Google LLC
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 #include "include/core/SkString.h"
8 #include "include/gpu/graphite/vk/VulkanGraphiteTypes.h"
9 #include "include/gpu/vk/VulkanMutableTextureState.h"
10 #include "src/gpu/graphite/TextureInfoPriv.h"
11 #include "src/gpu/graphite/vk/VulkanGraphiteTypesPriv.h"
12 #include "src/gpu/vk/VulkanUtilsPriv.h"
13
14 #include <cstdint>
15
16 namespace skgpu::graphite {
17
18 class VulkanTextureInfoData final : public TextureInfoData {
19 public:
VulkanTextureInfoData(VulkanTextureSpec v)20 VulkanTextureInfoData(VulkanTextureSpec v) : fVkSpec(v) {}
21
22 #if defined(SK_DEBUG)
type() const23 skgpu::BackendApi type() const override { return skgpu::BackendApi::kVulkan; }
24 #endif
25
spec() const26 VulkanTextureSpec spec() const { return fVkSpec; }
27
28 private:
29 VulkanTextureSpec fVkSpec;
30
bytesPerPixel() const31 size_t bytesPerPixel() const override { return VkFormatBytesPerBlock(fVkSpec.fFormat); }
32
compressionType() const33 SkTextureCompressionType compressionType() const override {
34 return VkFormatToCompressionType(fVkSpec.fFormat);
35 }
36
isMemoryless() const37 bool isMemoryless() const override {
38 return fVkSpec.fImageUsageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
39 }
40
toString() const41 SkString toString() const override {
42 return SkStringPrintf("Vulkan(%s,", fVkSpec.toString().c_str());
43 }
44
toRPAttachmentString(uint32_t sampleCount) const45 SkString toRPAttachmentString(uint32_t sampleCount) const override {
46 return SkStringPrintf(
47 "Vulkan(f=%u,s=%u)", static_cast<unsigned int>(fVkSpec.fFormat), sampleCount);
48 }
49
copyTo(AnyTextureInfoData & dstData) const50 void copyTo(AnyTextureInfoData& dstData) const override {
51 // Don't assert that dstData has a Vulkan type() because it could be
52 // uninitialized and that assert would fail.
53 dstData.emplace<VulkanTextureInfoData>(fVkSpec);
54 }
55
equal(const TextureInfoData * that) const56 bool equal(const TextureInfoData* that) const override {
57 SkASSERT(!that || that->type() == skgpu::BackendApi::kVulkan);
58 if (auto otherVk = static_cast<const VulkanTextureInfoData*>(that)) {
59 return fVkSpec == otherVk->fVkSpec;
60 }
61 return false;
62 }
63
isCompatible(const TextureInfoData * that) const64 bool isCompatible(const TextureInfoData* that) const override {
65 SkASSERT(!that || that->type() == skgpu::BackendApi::kVulkan);
66 if (auto otherVk = static_cast<const VulkanTextureInfoData*>(that)) {
67 return fVkSpec.isCompatible(otherVk->fVkSpec);
68 }
69 return false;
70 }
71 };
72
get_and_cast_data(const TextureInfo & info)73 static const VulkanTextureInfoData* get_and_cast_data(const TextureInfo& info) {
74 auto data = TextureInfoPriv::GetData(info);
75 SkASSERT(!data || data->type() == skgpu::BackendApi::kVulkan);
76 return static_cast<const VulkanTextureInfoData*>(data);
77 }
78
79 namespace TextureInfos {
MakeVulkan(const VulkanTextureInfo & vkInfo)80 TextureInfo MakeVulkan(const VulkanTextureInfo& vkInfo) {
81 skgpu::Protected p = Protected::kNo;
82 if (vkInfo.fFlags & VK_IMAGE_CREATE_PROTECTED_BIT) {
83 p = Protected::kYes;
84 }
85 return TextureInfoPriv::Make(skgpu::BackendApi::kVulkan,
86 vkInfo.fSampleCount,
87 vkInfo.fMipmapped,
88 p,
89 VulkanTextureInfoData(vkInfo));
90 }
91
GetVulkanTextureInfo(const TextureInfo & info,VulkanTextureInfo * out)92 bool GetVulkanTextureInfo(const TextureInfo& info, VulkanTextureInfo* out) {
93 if (!info.isValid() || info.backend() != skgpu::BackendApi::kVulkan) {
94 return false;
95 }
96 SkASSERT(out);
97 const VulkanTextureInfoData* vkData = get_and_cast_data(info);
98 SkASSERT(vkData);
99 *out = VulkanTextureSpecToTextureInfo(vkData->spec(), info.numSamples(), info.mipmapped());
100 return true;
101 }
102
103 // This cannot return a const reference or we get a warning about returning
104 // a reference to a temporary local variable.
GetVulkanTextureSpec(const TextureInfo & info)105 VulkanTextureSpec GetVulkanTextureSpec(const TextureInfo& info) {
106 SkASSERT(info.isValid() && info.backend() == skgpu::BackendApi::kVulkan);
107 const VulkanTextureInfoData* vkData = get_and_cast_data(info);
108 SkASSERT(vkData);
109 return vkData->spec();
110 }
111
GetVkFormat(const TextureInfo & info)112 VkFormat GetVkFormat(const TextureInfo& info) {
113 SkASSERT(info.isValid() && info.backend() == skgpu::BackendApi::kVulkan);
114 const VulkanTextureInfoData* vkData = get_and_cast_data(info);
115 SkASSERT(vkData);
116 return vkData->spec().fFormat;
117 }
118
GetVkUsageFlags(const TextureInfo & info)119 VkImageUsageFlags GetVkUsageFlags(const TextureInfo& info) {
120 SkASSERT(info.isValid() && info.backend() == skgpu::BackendApi::kVulkan);
121 const VulkanTextureInfoData* vkData = get_and_cast_data(info);
122 SkASSERT(vkData);
123 return vkData->spec().fImageUsageFlags;
124 }
125
GetVulkanYcbcrConversionInfo(const TextureInfo & info)126 VulkanYcbcrConversionInfo GetVulkanYcbcrConversionInfo(const TextureInfo& info) {
127 SkASSERT(info.isValid() && info.backend() == skgpu::BackendApi::kVulkan);
128 const VulkanTextureInfoData* vkData = get_and_cast_data(info);
129 SkASSERT(vkData);
130 return vkData->spec().fYcbcrConversionInfo;
131 }
132
133 } // namespace TextureInfos
134
135 } // namespace skgpu::graphite
136