Flutter Engine
The Flutter Engine
DawnTexture.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2022 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
9
14#include "src/core/SkMipmap.h"
19
20namespace skgpu::graphite {
21
22wgpu::Texture DawnTexture::MakeDawnTexture(const DawnSharedContext* sharedContext,
23 SkISize dimensions,
24 const TextureInfo& info) {
25 const Caps* caps = sharedContext->caps();
26 if (dimensions.width() > caps->maxTextureSize() ||
27 dimensions.height() > caps->maxTextureSize()) {
28 SKGPU_LOG_E("Texture creation failure: dimensions %d x %d too large.",
30 return {};
31 }
32
33 const DawnTextureSpec& dawnSpec = info.dawnTextureSpec();
34
35 if (dawnSpec.fUsage & wgpu::TextureUsage::TextureBinding && !caps->isTexturable(info)) {
36 return {};
37 }
38
39 if (dawnSpec.fUsage & wgpu::TextureUsage::RenderAttachment &&
40 !(caps->isRenderable(info) || DawnFormatIsDepthOrStencil(dawnSpec.fFormat))) {
41 return {};
42 }
43
44 if (dawnSpec.fUsage & wgpu::TextureUsage::StorageBinding && !caps->isStorage(info)) {
45 return {};
46 }
47
48 int numMipLevels = 1;
49 if (info.mipmapped() == Mipmapped::kYes) {
51 }
52
53 wgpu::TextureDescriptor desc;
54 desc.usage = dawnSpec.fUsage;
55 desc.dimension = wgpu::TextureDimension::e2D;
56 desc.size.width = dimensions.width();
57 desc.size.height = dimensions.height();
58 desc.size.depthOrArrayLayers = 1;
59 desc.format = dawnSpec.fFormat;
60 desc.mipLevelCount = numMipLevels;
61 desc.sampleCount = info.numSamples();
62 desc.viewFormatCount = 0;
63 desc.viewFormats = nullptr;
64
65 auto texture = sharedContext->device().CreateTexture(&desc);
66 if (!texture) {
67 return {};
68 }
69
70 return texture;
71}
72
73DawnTexture::DawnTexture(const DawnSharedContext* sharedContext,
74 SkISize dimensions,
75 const TextureInfo& info,
76 wgpu::Texture texture,
77 wgpu::TextureView sampleTextureView,
78 wgpu::TextureView renderTextureView,
79 Ownership ownership,
80 skgpu::Budgeted budgeted)
81 : Texture(sharedContext,
82 dimensions,
83 info,
84 /*mutableState=*/nullptr,
85 ownership,
86 budgeted)
87 , fTexture(std::move(texture))
88 , fSampleTextureView(std::move(sampleTextureView))
89 , fRenderTextureView(std::move(renderTextureView)) {}
90
91// static
92std::pair<wgpu::TextureView, wgpu::TextureView> DawnTexture::CreateTextureViews(
93 const wgpu::Texture& texture, const TextureInfo& info) {
94 const auto aspect = info.dawnTextureSpec().fAspect;
95 if (aspect == wgpu::TextureAspect::All) {
96 wgpu::TextureViewDescriptor viewDesc = {};
97 viewDesc.dimension = wgpu::TextureViewDimension::e2D;
98 viewDesc.baseArrayLayer = info.dawnTextureSpec().fSlice;
99 viewDesc.arrayLayerCount = 1;
100 wgpu::TextureView sampleTextureView = texture.CreateView(&viewDesc);
101 wgpu::TextureView renderTextureView;
102 if (info.mipmapped() == Mipmapped::kYes) {
103 viewDesc.baseMipLevel = 0;
104 viewDesc.mipLevelCount = 1;
105 renderTextureView = texture.CreateView(&viewDesc);
106 } else {
108 }
110 }
111
112#if defined(__EMSCRIPTEN__)
113 SkASSERT(false);
114 return {};
115#else
116 SkASSERT(aspect == wgpu::TextureAspect::Plane0Only ||
117 aspect == wgpu::TextureAspect::Plane1Only ||
118 aspect == wgpu::TextureAspect::Plane2Only);
119 wgpu::TextureView planeTextureView;
120 wgpu::TextureViewDescriptor planeViewDesc = {};
121 planeViewDesc.format = info.dawnTextureSpec().fViewFormat;
122 planeViewDesc.dimension = wgpu::TextureViewDimension::e2D;
123 planeViewDesc.aspect = aspect;
124 planeViewDesc.baseArrayLayer = info.dawnTextureSpec().fSlice;
125 planeViewDesc.arrayLayerCount = 1;
126 planeTextureView = texture.CreateView(&planeViewDesc);
127 return {planeTextureView, planeTextureView};
128#endif
129}
130
132 SkISize dimensions,
133 const TextureInfo& info,
134 skgpu::Budgeted budgeted) {
136 if (!texture) {
137 return {};
138 }
139 auto [sampleTextureView, renderTextureView] = CreateTextureViews(texture, info);
142 info,
143 std::move(texture),
144 std::move(sampleTextureView),
145 std::move(renderTextureView),
147 budgeted));
148}
149
151 SkISize dimensions,
152 const TextureInfo& info,
153 wgpu::Texture texture) {
154 if (!texture) {
155 SKGPU_LOG_E("No valid texture passed into MakeWrapped\n");
156 return {};
157 }
158
159 auto [sampleTextureView, renderTextureView] = CreateTextureViews(texture, info);
162 info,
163 std::move(texture),
164 std::move(sampleTextureView),
165 std::move(renderTextureView),
168}
169
171 SkISize dimensions,
172 const TextureInfo& info,
173 const wgpu::TextureView& textureView) {
174 if (!textureView) {
175 SKGPU_LOG_E("No valid texture view passed into MakeWrapped\n");
176 return {};
177 }
180 info,
181 /*texture=*/nullptr,
182 /*sampleTextureView=*/textureView,
183 /*renderTextureView=*/textureView,
186}
187
188void DawnTexture::freeGpuData() {
189 if (this->ownership() != Ownership::kWrapped && fTexture) {
190 // Destroy the texture even if it is still referenced by other BindGroup or views.
191 // Graphite should already guarantee that all command buffers using this texture (indirectly
192 // via BindGroup or views) are already completed.
193 fTexture.Destroy();
194 }
195 fTexture = nullptr;
196 fSampleTextureView = nullptr;
197 fRenderTextureView = nullptr;
198}
199
200void DawnTexture::setBackendLabel(char const* label) {
201 if (!sharedContext()->caps()->setBackendLabels()) {
202 return;
203 }
204 SkASSERT(label);
205 // Wrapped texture views won't have an associated texture here.
206 if (fTexture) {
207 fTexture.SetLabel(label);
208 }
209 // But we always have the texture views available.
210 SkASSERT(fSampleTextureView);
211 SkASSERT(fRenderTextureView);
212 if (fSampleTextureView.Get() == fRenderTextureView.Get()) {
213 fSampleTextureView.SetLabel(SkStringPrintf("%s_%s", label, "_TextureView").c_str());
214 } else {
215 fSampleTextureView.SetLabel(SkStringPrintf("%s_%s", label, "_SampleTextureView").c_str());
216 fRenderTextureView.SetLabel(SkStringPrintf("%s_%s", label, "_RenderTextureView").c_str());
217 }
218}
219
220} // namespace skgpu::graphite
221
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
#define SKGPU_LOG_E(fmt,...)
Definition: Log.h:38
#define SkASSERT(cond)
Definition: SkAssert.h:116
SK_API SkString SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
static int ComputeLevelCount(int baseWidth, int baseHeight)
Definition: SkMipmap.cpp:134
bool isTexturable(const TextureInfo &) const
Definition: Caps.cpp:66
virtual bool isStorage(const TextureInfo &) const =0
virtual bool isRenderable(const TextureInfo &) const =0
int maxTextureSize() const
Definition: Caps.h:141
static sk_sp< Texture > MakeWrapped(const DawnSharedContext *, SkISize dimensions, const TextureInfo &, wgpu::Texture)
static wgpu::Texture MakeDawnTexture(const DawnSharedContext *, SkISize dimensions, const TextureInfo &)
Definition: DawnTexture.cpp:22
const wgpu::TextureView & renderTextureView() const
Definition: DawnTexture.h:44
const wgpu::TextureView & sampleTextureView() const
Definition: DawnTexture.h:43
static sk_sp< Texture > Make(const DawnSharedContext *, SkISize dimensions, const TextureInfo &, skgpu::Budgeted)
skgpu::Budgeted budgeted() const
Definition: Resource.h:100
const SharedContext * sharedContext() const
Definition: Resource.h:189
Ownership ownership() const
Definition: Resource.h:98
const Caps * caps() const
Definition: SharedContext.h:39
SkISize dimensions() const
Definition: Texture.h:31
FlTexture * texture
bool DawnFormatIsDepthOrStencil(wgpu::TextureFormat format)
Budgeted
Definition: GpuTypes.h:35
Definition: ref_ptr.h:256
Definition: SkSize.h:16
constexpr int32_t width() const
Definition: SkSize.h:36
constexpr int32_t height() const
Definition: SkSize.h:37