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