1 /*
2 * Copyright 2021 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
8 #include "include/gpu/graphite/BackendTexture.h"
9
10 #include "include/gpu/MutableTextureState.h"
11
12 #ifdef SK_DAWN
13 #include "include/private/gpu/graphite/DawnTypesPriv.h"
14 #endif
15
16 #ifdef SK_VULKAN
17 #include "include/gpu/vk/VulkanMutableTextureState.h"
18 #endif
19
20 namespace skgpu::graphite {
21
22 BackendTexture::BackendTexture() = default;
23
24 BackendTexture::~BackendTexture() = default;
25
BackendTexture(const BackendTexture & that)26 BackendTexture::BackendTexture(const BackendTexture& that) {
27 *this = that;
28 }
29
operator =(const BackendTexture & that)30 BackendTexture& BackendTexture::operator=(const BackendTexture& that) {
31 if (!that.isValid()) {
32 fInfo = {};
33 return *this;
34 }
35 // We shouldn't be mixing backends.
36 SkASSERT(!this->isValid() || this->backend() == that.backend());
37 fDimensions = that.fDimensions;
38 fInfo = that.fInfo;
39
40 switch (that.backend()) {
41 #ifdef SK_DAWN
42 case BackendApi::kDawn:
43 fDawnTexture = that.fDawnTexture;
44 fDawnTextureView = that.fDawnTextureView;
45 break;
46 #endif
47 #ifdef SK_METAL
48 case BackendApi::kMetal:
49 fMtlTexture = that.fMtlTexture;
50 break;
51 #endif
52 #ifdef SK_VULKAN
53 case BackendApi::kVulkan:
54 fVkImage = that.fVkImage;
55 fMutableState = that.fMutableState;
56 fMemoryAlloc = that.fMemoryAlloc;
57 break;
58 #endif
59 default:
60 SK_ABORT("Unsupported Backend");
61 }
62 return *this;
63 }
64
operator ==(const BackendTexture & that) const65 bool BackendTexture::operator==(const BackendTexture& that) const {
66 if (!this->isValid() || !that.isValid()) {
67 return false;
68 }
69
70 if (fDimensions != that.fDimensions || fInfo != that.fInfo) {
71 return false;
72 }
73
74 switch (that.backend()) {
75 #ifdef SK_DAWN
76 case BackendApi::kDawn:
77 if (fDawnTexture != that.fDawnTexture) {
78 return false;
79 }
80 if (fDawnTextureView != that.fDawnTextureView) {
81 return false;
82 }
83 break;
84 #endif
85 #ifdef SK_METAL
86 case BackendApi::kMetal:
87 if (fMtlTexture != that.fMtlTexture) {
88 return false;
89 }
90 break;
91 #endif
92 #ifdef SK_VULKAN
93 case BackendApi::kVulkan:
94 if (fVkImage != that.fVkImage) {
95 return false;
96 }
97 break;
98 #endif
99 default:
100 SK_ABORT("Unsupported Backend");
101 }
102 return true;
103 }
104
setMutableState(const skgpu::MutableTextureState & newState)105 void BackendTexture::setMutableState(const skgpu::MutableTextureState& newState) {
106 fMutableState->set(newState);
107 }
108
getMutableState() const109 sk_sp<MutableTextureState> BackendTexture::getMutableState() const {
110 return fMutableState;
111 }
112
113 #ifdef SK_DAWN
BackendTexture(WGPUTexture texture)114 BackendTexture::BackendTexture(WGPUTexture texture)
115 : fDimensions{static_cast<int32_t>(wgpuTextureGetWidth(texture)),
116 static_cast<int32_t>(wgpuTextureGetHeight(texture))}
117 , fInfo(DawnTextureInfoFromWGPUTexture(texture))
118 , fDawnTexture(texture)
119 , fDawnTextureView(nullptr) {}
120
BackendTexture(SkISize planeDimensions,const DawnTextureInfo & info,WGPUTexture texture)121 BackendTexture::BackendTexture(SkISize planeDimensions,
122 const DawnTextureInfo& info,
123 WGPUTexture texture)
124 : fDimensions(planeDimensions)
125 , fInfo(info)
126 , fDawnTexture(texture)
127 , fDawnTextureView(nullptr) {
128
129 #if defined(__EMSCRIPTEN__)
130 SkASSERT(info.fAspect == wgpu::TextureAspect::All);
131 #else
132 SkASSERT(info.fAspect == wgpu::TextureAspect::All ||
133 info.fAspect == wgpu::TextureAspect::Plane0Only ||
134 info.fAspect == wgpu::TextureAspect::Plane1Only ||
135 info.fAspect == wgpu::TextureAspect::Plane2Only);
136 #endif
137 }
138
139 // When we only have a WGPUTextureView we can't actually take advantage of these TextureUsage bits
140 // because they require having the WGPUTexture.
strip_copy_usage(const DawnTextureInfo & info)141 static DawnTextureInfo strip_copy_usage(const DawnTextureInfo& info) {
142 DawnTextureInfo result = info;
143 result.fUsage &= ~(wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::CopySrc);
144 return result;
145 }
146
BackendTexture(SkISize dimensions,const DawnTextureInfo & info,WGPUTextureView textureView)147 BackendTexture::BackendTexture(SkISize dimensions,
148 const DawnTextureInfo& info,
149 WGPUTextureView textureView)
150 : fDimensions(dimensions)
151 , fInfo(strip_copy_usage(info))
152 , fDawnTexture(nullptr)
153 , fDawnTextureView(textureView) {}
154
getDawnTexturePtr() const155 WGPUTexture BackendTexture::getDawnTexturePtr() const {
156 if (this->isValid() && this->backend() == BackendApi::kDawn) {
157 return fDawnTexture;
158 }
159 return {};
160 }
161
getDawnTextureViewPtr() const162 WGPUTextureView BackendTexture::getDawnTextureViewPtr() const {
163 if (this->isValid() && this->backend() == BackendApi::kDawn) {
164 return fDawnTextureView;
165 }
166 return {};
167 }
168 #endif
169
170 #ifdef SK_METAL
BackendTexture(SkISize dimensions,CFTypeRef mtlTexture)171 BackendTexture::BackendTexture(SkISize dimensions, CFTypeRef mtlTexture)
172 : fDimensions(dimensions)
173 , fInfo(MtlTextureInfo(mtlTexture))
174 , fMtlTexture(mtlTexture) {}
175
getMtlTexture() const176 CFTypeRef BackendTexture::getMtlTexture() const {
177 if (this->isValid() && this->backend() == BackendApi::kMetal) {
178 return fMtlTexture;
179 }
180 return nullptr;
181 }
182 #endif // SK_METAL
183
184 #ifdef SK_VULKAN
BackendTexture(SkISize dimensions,const VulkanTextureInfo & info,VkImageLayout layout,uint32_t queueFamilyIndex,VkImage image,VulkanAlloc vulkanMemoryAllocation)185 BackendTexture::BackendTexture(SkISize dimensions,
186 const VulkanTextureInfo& info,
187 VkImageLayout layout,
188 uint32_t queueFamilyIndex,
189 VkImage image,
190 VulkanAlloc vulkanMemoryAllocation)
191 : fDimensions(dimensions)
192 , fInfo(info)
193 , fMutableState(sk_make_sp<skgpu::MutableTextureState>(
194 skgpu::MutableTextureStates::MakeVulkan(layout, queueFamilyIndex)))
195 , fMemoryAlloc(vulkanMemoryAllocation)
196 , fVkImage(image) {}
197
getVkImage() const198 VkImage BackendTexture::getVkImage() const {
199 if (this->isValid() && this->backend() == BackendApi::kVulkan) {
200 return fVkImage;
201 }
202 return VK_NULL_HANDLE;
203 }
204
getVkImageLayout() const205 VkImageLayout BackendTexture::getVkImageLayout() const {
206 if (this->isValid() && this->backend() == BackendApi::kVulkan) {
207 SkASSERT(fMutableState);
208 return skgpu::MutableTextureStates::GetVkImageLayout(fMutableState.get());
209 }
210 return VK_IMAGE_LAYOUT_UNDEFINED;
211 }
212
getVkQueueFamilyIndex() const213 uint32_t BackendTexture::getVkQueueFamilyIndex() const {
214 if (this->isValid() && this->backend() == BackendApi::kVulkan) {
215 SkASSERT(fMutableState);
216 return skgpu::MutableTextureStates::GetVkQueueFamilyIndex(fMutableState.get());
217 }
218 return 0;
219 }
220
getMemoryAlloc() const221 const VulkanAlloc* BackendTexture::getMemoryAlloc() const {
222 if (this->isValid() && this->backend() == BackendApi::kVulkan) {
223 return &fMemoryAlloc;
224 }
225 return {};
226 }
227 #endif // SK_VULKAN
228
229 } // namespace skgpu::graphite
230
231