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/SkStream.h"
8 #include "include/core/SkString.h"
9 #include "include/gpu/graphite/dawn/DawnGraphiteTypes.h"
10 #include "src/gpu/graphite/TextureInfoPriv.h"
11 #include "src/gpu/graphite/dawn/DawnGraphiteUtils.h"
12
13 #include <cstdint>
14
15 namespace skgpu::graphite {
16
DawnTextureInfo(WGPUTexture texture)17 DawnTextureInfo::DawnTextureInfo(WGPUTexture texture)
18 : DawnTextureInfo(
19 wgpuTextureGetSampleCount(texture),
20 wgpuTextureGetMipLevelCount(texture) > 1 ? Mipmapped::kYes : Mipmapped::kNo,
21 /*format=*/static_cast<wgpu::TextureFormat>(wgpuTextureGetFormat(texture)),
22 /*viewFormat=*/static_cast<wgpu::TextureFormat>(wgpuTextureGetFormat(texture)),
23 static_cast<wgpu::TextureUsage>(wgpuTextureGetUsage(texture)),
24 wgpu::TextureAspect::All,
25 /*slice=*/0) {}
26
viewFormat() const27 TextureFormat DawnTextureInfo::viewFormat() const {
28 #if !defined(__EMSCRIPTEN__)
29 if (fYcbcrVkDescriptor.externalFormat != 0) {
30 return TextureFormat::kExternal;
31 }
32 #endif
33 return DawnFormatToTextureFormat(this->getViewFormat());
34 }
35
toBackendString() const36 SkString DawnTextureInfo::toBackendString() const {
37 return SkStringPrintf("wgpuFormat=%u,usage=0x%08X,aspect=0x%08X,slice=%u",
38 static_cast<unsigned int>(fFormat),
39 static_cast<unsigned int>(fUsage),
40 static_cast<unsigned int>(fAspect),
41 fSlice);
42 }
43
isCompatible(const TextureInfo & that,bool requireExact) const44 bool DawnTextureInfo::isCompatible(const TextureInfo& that, bool requireExact) const {
45 const auto& dt = TextureInfoPriv::Get<DawnTextureInfo>(that);
46
47 // The usages may match or the usage passed in may be a superset of the usage stored within. The
48 // YCbCrInfo must be equal. The aspect should either match the plane aspect or should be All.
49 return this->getViewFormat() == dt.getViewFormat() &&
50 (fUsage & dt.fUsage) == fUsage &&
51 #if !defined(__EMSCRIPTEN__)
52 DawnDescriptorsAreEquivalent(fYcbcrVkDescriptor, dt.fYcbcrVkDescriptor) &&
53 #endif
54 (fAspect == dt.fAspect || (!requireExact && fAspect == wgpu::TextureAspect::All));
55 }
56
serialize(SkWStream * stream) const57 bool DawnTextureInfo::serialize(SkWStream* stream) const {
58
59 if (!stream->write32(static_cast<uint32_t>(fFormat))) { return false; }
60 if (!stream->write32(static_cast<uint32_t>(fViewFormat))) { return false; }
61 if (!stream->write64(static_cast<uint64_t>(fUsage))) { return false; }
62 if (!stream->write32(static_cast<uint32_t>(fAspect))) { return false; }
63 if (!stream->write32(fSlice)) { return false; }
64
65 #if !defined(__EMSCRIPTEN__)
66 bool hasYCbCr = DawnDescriptorIsValid(fYcbcrVkDescriptor);
67 if (!stream->writeBool(hasYCbCr)) { return false; }
68
69 if (hasYCbCr) {
70 SkASSERT(SkTFitsIn<uint8_t>(fYcbcrVkDescriptor.vkChromaFilter));
71
72 // Except for the last three members, Dawn stores these all as uint32_ts although the
73 // values stored within them will usually need far fewer bits.
74 if (!stream->write32(fYcbcrVkDescriptor.vkFormat)) { return false; }
75 if (!stream->write32(fYcbcrVkDescriptor.vkYCbCrModel)) { return false; }
76 if (!stream->write32(fYcbcrVkDescriptor.vkYCbCrRange)) { return false; }
77 if (!stream->write32(fYcbcrVkDescriptor.vkComponentSwizzleRed)) { return false; }
78 if (!stream->write32(fYcbcrVkDescriptor.vkComponentSwizzleGreen)) { return false; }
79 if (!stream->write32(fYcbcrVkDescriptor.vkComponentSwizzleBlue)) { return false; }
80 if (!stream->write32(fYcbcrVkDescriptor.vkComponentSwizzleAlpha)) { return false; }
81 if (!stream->write32(fYcbcrVkDescriptor.vkXChromaOffset)) { return false; }
82 if (!stream->write32(fYcbcrVkDescriptor.vkYChromaOffset)) { return false; }
83 if (!stream->write32(static_cast<uint32_t>(fYcbcrVkDescriptor.vkChromaFilter))) {
84 return false;
85 }
86 if (!stream->writeBool(fYcbcrVkDescriptor.forceExplicitReconstruction)) {
87 return false;
88 }
89 if (!stream->write64(fYcbcrVkDescriptor.externalFormat)) { return false; }
90 }
91 #endif
92
93 return true;
94 }
95
deserialize(SkStream * stream)96 bool DawnTextureInfo::deserialize(SkStream* stream) {
97 uint32_t tmp32;
98
99 if (!stream->readU32(&tmp32)) {
100 return false;
101 }
102 // TODO(robertphillips): add validity checks to deserialized values
103 fFormat = static_cast<wgpu::TextureFormat>(tmp32);
104
105 if (!stream->readU32(&tmp32)) {
106 return false;
107 }
108 fViewFormat = static_cast<wgpu::TextureFormat>(tmp32);
109
110 uint64_t tmp64;
111 if (!stream->readU64(&tmp64)) {
112 return false;
113 }
114 fUsage = static_cast<wgpu::TextureUsage>(tmp64);
115
116 if (!stream->readU32(&tmp32)) {
117 return false;
118 }
119 fAspect = static_cast<wgpu::TextureAspect>(tmp32);
120
121 if (!stream->readU32(&fSlice)) {
122 return false;
123 }
124
125 #if !defined(__EMSCRIPTEN__)
126 bool tmpBool;
127 if (!stream->readBool(&tmpBool)) {
128 return false;
129 }
130
131 if (/* hasYbCr */ tmpBool) {
132 if (!stream->readU32(&fYcbcrVkDescriptor.vkFormat)) { return false; }
133 if (!stream->readU32(&fYcbcrVkDescriptor.vkYCbCrModel)) { return false; }
134 if (!stream->readU32(&fYcbcrVkDescriptor.vkYCbCrRange)) { return false; }
135 if (!stream->readU32(&fYcbcrVkDescriptor.vkComponentSwizzleRed)) { return false; }
136 if (!stream->readU32(&fYcbcrVkDescriptor.vkComponentSwizzleGreen)) { return false; }
137 if (!stream->readU32(&fYcbcrVkDescriptor.vkComponentSwizzleBlue)) { return false; }
138 if (!stream->readU32(&fYcbcrVkDescriptor.vkComponentSwizzleAlpha)) { return false; }
139 if (!stream->readU32(&fYcbcrVkDescriptor.vkXChromaOffset)) { return false; }
140 if (!stream->readU32(&fYcbcrVkDescriptor.vkYChromaOffset)) { return false; }
141
142 if (!stream->readU32(&tmp32)) { return false; }
143 fYcbcrVkDescriptor.vkChromaFilter = static_cast<wgpu::FilterMode>(tmp32);
144 if (!stream->readBool(&tmpBool)) { return false; }
145 fYcbcrVkDescriptor.forceExplicitReconstruction = tmpBool;
146
147 if (!stream->readU64(&fYcbcrVkDescriptor.externalFormat)) { return false; }
148 }
149 #endif
150
151 return true;
152 }
153
154 namespace TextureInfos {
155
MakeDawn(const DawnTextureInfo & dawnInfo)156 TextureInfo MakeDawn(const DawnTextureInfo& dawnInfo) {
157 return TextureInfoPriv::Make(dawnInfo);
158 }
159
GetDawnTextureInfo(const TextureInfo & info,DawnTextureInfo * out)160 bool GetDawnTextureInfo(const TextureInfo& info, DawnTextureInfo* out) {
161 return TextureInfoPriv::Copy(info, out);
162 }
163
164 } // namespace TextureInfos
165
166 } // namespace skgpu::graphite
167