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/dawn/DawnTypes.h"
9 #include "src/gpu/graphite/BackendTexturePriv.h"
10 #include "src/gpu/graphite/dawn/DawnGraphiteTypesPriv.h"
11 #include "src/gpu/graphite/dawn/DawnUtilsPriv.h"
12
13 #include "webgpu/webgpu_cpp.h" // NO_G3_REWRITE
14
15 #include <cstdint>
16
17 namespace skgpu::graphite {
18
19 class DawnBackendTextureData final : public BackendTextureData {
20 public:
DawnBackendTextureData(WGPUTexture tex,WGPUTextureView tv)21 DawnBackendTextureData(WGPUTexture tex, WGPUTextureView tv) : fTexture(tex), fTextureView(tv) {}
22
23 #if defined(SK_DEBUG)
type() const24 skgpu::BackendApi type() const override { return skgpu::BackendApi::kDawn; }
25 #endif
26
texture() const27 WGPUTexture texture() const { return fTexture; }
textureView() const28 WGPUTextureView textureView() const { return fTextureView; }
29
30 private:
31 WGPUTexture fTexture;
32 WGPUTextureView fTextureView;
33
copyTo(AnyBackendTextureData & dstData) const34 void copyTo(AnyBackendTextureData& dstData) const override {
35 // Don't assert that dstData has a Dawn type() because it could be
36 // uninitialized and that assert would fail.
37 dstData.emplace<DawnBackendTextureData>(fTexture, fTextureView);
38 }
39
equal(const BackendTextureData * that) const40 bool equal(const BackendTextureData* that) const override {
41 SkASSERT(!that || that->type() == skgpu::BackendApi::kDawn);
42 if (auto otherDawn = static_cast<const DawnBackendTextureData*>(that)) {
43 return fTexture == otherDawn->fTexture && fTextureView == otherDawn->fTextureView;
44 }
45 return false;
46 }
47 };
48
get_and_cast_data(const BackendTexture & tex)49 static const DawnBackendTextureData* get_and_cast_data(const BackendTexture& tex) {
50 auto data = BackendTexturePriv::GetData(tex);
51 SkASSERT(!data || data->type() == skgpu::BackendApi::kDawn);
52 return static_cast<const DawnBackendTextureData*>(data);
53 }
54
55 // When we only have a WGPUTextureView we can't actually take advantage of these TextureUsage bits
56 // because they require having the WGPUTexture.
strip_copy_usage(const DawnTextureInfo & info)57 static DawnTextureInfo strip_copy_usage(const DawnTextureInfo& info) {
58 DawnTextureInfo result = info;
59 result.fUsage &= ~(wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::CopySrc);
60 return result;
61 }
62
63 namespace BackendTextures {
MakeDawn(WGPUTexture texture)64 BackendTexture MakeDawn(WGPUTexture texture) {
65 return BackendTexturePriv::Make(
66 {
67 static_cast<int32_t>(wgpuTextureGetWidth(texture)),
68 static_cast<int32_t>(wgpuTextureGetHeight(texture)),
69 },
70 TextureInfos::MakeDawn(DawnTextureInfoFromWGPUTexture(texture)),
71 DawnBackendTextureData(texture, nullptr));
72 }
73
MakeDawn(SkISize planeDimensions,const DawnTextureInfo & info,WGPUTexture texture)74 BackendTexture MakeDawn(SkISize planeDimensions, const DawnTextureInfo& info, WGPUTexture texture) {
75 #if defined(__EMSCRIPTEN__)
76 SkASSERT(info.fAspect == wgpu::TextureAspect::All);
77 #else
78 SkASSERT(info.fAspect == wgpu::TextureAspect::All ||
79 info.fAspect == wgpu::TextureAspect::Plane0Only ||
80 info.fAspect == wgpu::TextureAspect::Plane1Only ||
81 info.fAspect == wgpu::TextureAspect::Plane2Only);
82 #endif
83 return BackendTexturePriv::Make(planeDimensions,
84 TextureInfos::MakeDawn(info),
85 DawnBackendTextureData(texture, nullptr));
86 }
87
MakeDawn(SkISize dimensions,const DawnTextureInfo & info,WGPUTextureView textureView)88 BackendTexture MakeDawn(SkISize dimensions,
89 const DawnTextureInfo& info,
90 WGPUTextureView textureView) {
91 return BackendTexturePriv::Make(dimensions,
92 TextureInfos::MakeDawn(strip_copy_usage(info)),
93 DawnBackendTextureData(nullptr, textureView));
94 }
95
GetDawnTexturePtr(const BackendTexture & tex)96 WGPUTexture GetDawnTexturePtr(const BackendTexture& tex) {
97 if (!tex.isValid() || tex.backend() != skgpu::BackendApi::kDawn) {
98 return nullptr;
99 }
100 const DawnBackendTextureData* dawnData = get_and_cast_data(tex);
101 SkASSERT(dawnData);
102 return dawnData->texture();
103 }
104
GetDawnTextureViewPtr(const BackendTexture & tex)105 WGPUTextureView GetDawnTextureViewPtr(const BackendTexture& tex) {
106 if (!tex.isValid() || tex.backend() != skgpu::BackendApi::kDawn) {
107 return nullptr;
108 }
109 const DawnBackendTextureData* dawnData = get_and_cast_data(tex);
110 SkASSERT(dawnData);
111 return dawnData->textureView();
112 }
113
114 } // namespace BackendTextures
115
116 } // namespace skgpu::graphite
117