• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2024 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 #ifndef LIBANGLE_RENDERER_WGPU_WGPU_HELPERS_H_
8 #define LIBANGLE_RENDERER_WGPU_WGPU_HELPERS_H_
9 
10 #include <dawn/webgpu_cpp.h>
11 #include <stdint.h>
12 
13 #include "libANGLE/Error.h"
14 #include "libANGLE/ImageIndex.h"
15 #include "libANGLE/angletypes.h"
16 #include "libANGLE/renderer/wgpu/ContextWgpu.h"
17 #include "libANGLE/renderer/wgpu/wgpu_utils.h"
18 
19 namespace rx
20 {
21 
22 class ContextWgpu;
23 
24 namespace webgpu
25 {
26 
27 // WebGPU requires copy buffers bytesPerRow to be aligned to 256.
28 // https://www.w3.org/TR/webgpu/#abstract-opdef-validating-gpuimagecopybuffer
29 static const GLuint kCopyBufferAlignment = 256;
30 
31 enum class UpdateSource
32 {
33     Clear,
34     Texture,
35 };
36 
37 struct SubresourceUpdate
38 {
SubresourceUpdateSubresourceUpdate39     SubresourceUpdate() {}
~SubresourceUpdateSubresourceUpdate40     ~SubresourceUpdate() {}
41 
SubresourceUpdateSubresourceUpdate42     SubresourceUpdate(UpdateSource targetUpdateSource,
43                       gl::LevelIndex newTargetLevel,
44                       wgpu::ImageCopyBuffer targetBuffer)
45     {
46         updateSource = targetUpdateSource;
47         textureData  = targetBuffer;
48         targetLevel  = newTargetLevel;
49     }
50 
SubresourceUpdateSubresourceUpdate51     SubresourceUpdate(UpdateSource targetUpdateSource,
52                       gl::LevelIndex newTargetLevel,
53                       ClearValues clearUpdate)
54     {
55         updateSource = targetUpdateSource;
56         targetLevel  = newTargetLevel;
57         clearData    = clearUpdate;
58     }
59 
60     UpdateSource updateSource;
61     ClearValues clearData;
62     wgpu::ImageCopyBuffer textureData;
63 
64     gl::LevelIndex targetLevel;
65 };
66 
67 wgpu::TextureDimension toWgpuTextureDimension(gl::TextureType glTextureType);
68 
69 class ImageHelper
70 {
71   public:
72     ImageHelper();
73     ~ImageHelper();
74 
75     angle::Result initImage(wgpu::Device &device,
76                             gl::LevelIndex firstAllocatedLevel,
77                             wgpu::TextureDescriptor textureDescriptor);
78 
79     angle::Result flushStagedUpdates(ContextWgpu *contextWgpu,
80                                      ClearValuesArray *deferredClears = nullptr,
81                                      uint32_t deferredClearIndex      = 0);
82 
83     wgpu::TextureDescriptor createTextureDescriptor(wgpu::TextureUsage usage,
84                                                     wgpu::TextureDimension dimension,
85                                                     wgpu::Extent3D size,
86                                                     wgpu::TextureFormat format,
87                                                     std::uint32_t mipLevelCount,
88                                                     std::uint32_t sampleCount);
89 
90     angle::Result stageTextureUpload(ContextWgpu *contextWgpu,
91                                      const gl::Extents &glExtents,
92                                      GLuint inputRowPitch,
93                                      GLuint inputDepthPitch,
94                                      uint32_t outputRowPitch,
95                                      uint32_t outputDepthPitch,
96                                      uint32_t allocationSize,
97                                      const gl::ImageIndex &index,
98                                      const uint8_t *pixels);
99 
100     void stageClear(gl::LevelIndex targetLevel, ClearValues clearValues);
101 
102     void removeStagedUpdates(gl::LevelIndex levelToRemove);
103 
104     void resetImage();
105 
106     static angle::Result getReadPixelsParams(rx::ContextWgpu *contextWgpu,
107                                              const gl::PixelPackState &packState,
108                                              gl::Buffer *packBuffer,
109                                              GLenum format,
110                                              GLenum type,
111                                              const gl::Rectangle &area,
112                                              const gl::Rectangle &clippedArea,
113                                              rx::PackPixelsParams *paramsOut,
114                                              GLuint *skipBytesOut);
115 
116     angle::Result readPixels(rx::ContextWgpu *contextWgpu,
117                              const gl::Rectangle &area,
118                              const rx::PackPixelsParams &packPixelsParams,
119                              const angle::Format &aspectFormat,
120                              void *pixels);
121 
122     angle::Result createTextureView(gl::LevelIndex targetLevel,
123                                     uint32_t layerIndex,
124                                     wgpu::TextureView &textureViewOut);
125     LevelIndex toWgpuLevel(gl::LevelIndex levelIndexGl) const;
126     gl::LevelIndex toGlLevel(LevelIndex levelIndexWgpu) const;
127     bool isTextureLevelInAllocatedImage(gl::LevelIndex textureLevel);
getTexture()128     wgpu::Texture &getTexture() { return mTexture; }
toWgpuTextureFormat()129     wgpu::TextureFormat toWgpuTextureFormat() const { return mTextureDescriptor.format; }
getTextureDescriptor()130     const wgpu::TextureDescriptor &getTextureDescriptor() const { return mTextureDescriptor; }
getFirstAllocatedLevel()131     gl::LevelIndex getFirstAllocatedLevel() { return mFirstAllocatedLevel; }
132     gl::LevelIndex getLastAllocatedLevel();
getLevelCount()133     uint32_t getLevelCount() { return mTextureDescriptor.mipLevelCount; }
getSize()134     wgpu::Extent3D getSize() { return mTextureDescriptor.size; }
isInitialized()135     bool isInitialized() { return mInitialized; }
136 
137   private:
138     wgpu::Texture mTexture;
139     wgpu::TextureDescriptor mTextureDescriptor = {};
140     std::vector<wgpu::TextureFormat> mViewFormats;
141     bool mInitialized = false;
142 
143     gl::LevelIndex mFirstAllocatedLevel = gl::LevelIndex(0);
144 
145     std::vector<SubresourceUpdate> mSubresourceQueue;
146 };
147 struct BufferMapState
148 {
149     wgpu::MapMode mode;
150     size_t offset;
151     size_t size;
152 };
153 
154 enum class MapAtCreation
155 {
156     No,
157     Yes,
158 };
159 
160 class BufferHelper : public angle::NonCopyable
161 {
162   public:
163     BufferHelper();
164     ~BufferHelper();
165 
valid()166     bool valid() const { return mBuffer != nullptr; }
167     void reset();
168 
169     angle::Result initBuffer(wgpu::Device device,
170                              size_t size,
171                              wgpu::BufferUsage usage,
172                              MapAtCreation mappedAtCreation);
173 
174     angle::Result mapImmediate(ContextWgpu *context,
175                                wgpu::MapMode mode,
176                                size_t offset,
177                                size_t size);
178     angle::Result unmap();
179 
180     uint8_t *getMapWritePointer(size_t offset, size_t size) const;
181     const uint8_t *getMapReadPointer(size_t offset, size_t size) const;
182 
183     const std::optional<BufferMapState> &getMappedState() const;
184 
185     bool canMapForRead() const;
186     bool canMapForWrite() const;
187 
188     wgpu::Buffer &getBuffer();
189     uint64_t size() const;
190 
191   private:
192     wgpu::Buffer mBuffer;
193 
194     std::optional<BufferMapState> mMappedState;
195 };
196 
197 }  // namespace webgpu
198 }  // namespace rx
199 #endif  // LIBANGLE_RENDERER_WGPU_WGPU_HELPERS_H_
200