xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/vulkan/CLMemoryVk.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2021 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 // CLMemoryVk.h: Defines the class interface for CLMemoryVk, implementing CLMemoryImpl.
7 
8 #ifndef LIBANGLE_RENDERER_VULKAN_CLMEMORYVK_H_
9 #define LIBANGLE_RENDERER_VULKAN_CLMEMORYVK_H_
10 
11 #include "common/PackedCLEnums_autogen.h"
12 #include "common/SimpleMutex.h"
13 
14 #include "libANGLE/renderer/vulkan/cl_types.h"
15 #include "libANGLE/renderer/vulkan/vk_helpers.h"
16 
17 #include "libANGLE/renderer/CLMemoryImpl.h"
18 
19 #include "libANGLE/CLBuffer.h"
20 #include "libANGLE/CLImage.h"
21 #include "libANGLE/CLMemory.h"
22 
23 #include "libANGLE/renderer/vulkan/vk_wrapper.h"
24 #include "vulkan/vulkan_core.h"
25 
26 namespace rx
27 {
28 
29 union PixelColor
30 {
31     uint8_t u8[4];
32     int8_t s8[4];
33     uint16_t u16[4];
34     int16_t s16[4];
35     uint32_t u32[4];
36     int32_t s32[4];
37     cl_half fp16[4];
38     cl_float fp32[4];
39 };
40 
41 class CLMemoryVk : public CLMemoryImpl
42 {
43   public:
44     ~CLMemoryVk() override;
45 
46     // TODO: http://anglebug.com/42267017
47     angle::Result createSubBuffer(const cl::Buffer &buffer,
48                                   cl::MemFlags flags,
49                                   size_t size,
50                                   CLMemoryImpl::Ptr *subBufferOut) override;
51 
52     angle::Result map(uint8_t *&ptrOut, size_t offset = 0);
unmap()53     void unmap() { unmapImpl(); }
54 
55     VkBufferUsageFlags getVkUsageFlags();
56     VkMemoryPropertyFlags getVkMemPropertyFlags();
57     virtual size_t getSize() const = 0;
getOffset()58     size_t getOffset() const { return mMemory.getOffset(); }
getFlags()59     cl::MemFlags getFlags() const { return mMemory.getFlags(); }
getType()60     cl::MemObjectType getType() const { return mMemory.getType(); }
61 
62     angle::Result copyTo(void *ptr, size_t offset, size_t size);
63     angle::Result copyTo(CLMemoryVk *dst, size_t srcOffset, size_t dstOffset, size_t size);
64     angle::Result copyFrom(const void *ptr, size_t offset, size_t size);
65 
isWritable()66     bool isWritable()
67     {
68         constexpr VkBufferUsageFlags kWritableUsage =
69             VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
70         return (getVkUsageFlags() & kWritableUsage) != 0;
71     }
72 
73     virtual bool isCurrentlyInUse() const = 0;
isMapped()74     bool isMapped() const { return mMappedMemory != nullptr; }
75 
76   protected:
77     CLMemoryVk(const cl::Memory &memory);
78 
79     virtual angle::Result mapImpl() = 0;
80     virtual void unmapImpl()        = 0;
81 
82     CLContextVk *mContext;
83     vk::Renderer *mRenderer;
84     vk::Allocation mAllocation;
85     angle::SimpleMutex mMapLock;
86     uint8_t *mMappedMemory;
87     uint32_t mMapCount;
88     CLMemoryVk *mParent;
89 };
90 
91 class CLBufferVk : public CLMemoryVk
92 {
93   public:
94     CLBufferVk(const cl::Buffer &buffer);
95     ~CLBufferVk() override;
96 
97     vk::BufferHelper &getBuffer();
getParent()98     CLBufferVk *getParent() { return static_cast<CLBufferVk *>(mParent); }
getFrontendObject()99     const cl::Buffer &getFrontendObject() { return reinterpret_cast<const cl::Buffer &>(mMemory); }
100 
101     angle::Result create(void *hostPtr);
102     angle::Result createStagingBuffer(size_t size);
103 
fillWithPattern(const void * pattern,size_t patternSize,size_t offset,size_t size)104     angle::Result fillWithPattern(const void *pattern,
105                                   size_t patternSize,
106                                   size_t offset,
107                                   size_t size)
108     {
109         getBuffer().fillWithPattern(pattern, patternSize, offset, size);
110         return angle::Result::Continue;
111     }
112 
isSubBuffer()113     bool isSubBuffer() const { return mParent != nullptr; }
114 
115     angle::Result setRect(const void *data,
116                           const cl::BufferRect &srcRect,
117                           const cl::BufferRect &bufferRect);
118     angle::Result getRect(const cl::BufferRect &srcRect,
119                           const cl::BufferRect &outRect,
120                           void *outData);
121 
122     bool isCurrentlyInUse() const override;
getSize()123     size_t getSize() const override { return mMemory.getSize(); }
124 
125   private:
126     angle::Result mapImpl() override;
127     void unmapImpl() override;
128 
129     angle::Result setDataImpl(const uint8_t *data, size_t size, size_t offset);
130 
131     vk::BufferHelper mBuffer;
132     VkBufferCreateInfo mDefaultBufferCreateInfo;
133 };
134 
135 class CLImageVk : public CLMemoryVk
136 {
137   public:
138     CLImageVk(const cl::Image &image);
139     ~CLImageVk() override;
140 
getImage()141     vk::ImageHelper &getImage() { return mImage; }
getStagingBuffer()142     vk::BufferHelper &getStagingBuffer() { return mStagingBuffer; }
getFrontendObject()143     const cl::Image &getFrontendObject() const
144     {
145         return reinterpret_cast<const cl::Image &>(mMemory);
146     }
getFormat()147     cl_image_format getFormat() const { return getFrontendObject().getFormat(); }
getDescriptor()148     cl::ImageDescriptor getDescriptor() const { return getFrontendObject().getDescriptor(); }
getElementSize()149     size_t getElementSize() const { return getFrontendObject().getElementSize(); }
getArraySize()150     size_t getArraySize() const { return getFrontendObject().getArraySize(); }
getSize()151     size_t getSize() const override { return mMemory.getSize(); }
152     size_t getRowPitch() const;
153     size_t getSlicePitch() const;
154 
155     cl::MemObjectType getParentType() const;
156     template <typename T>
157     T *getParent() const;
158 
159     angle::Result create(void *hostPtr);
160     angle::Result createFromBuffer();
161 
162     bool isCurrentlyInUse() const override;
163     bool containsHostMemExtension();
164 
165     angle::Result createStagingBuffer(size_t size);
166     angle::Result copyStagingFrom(void *ptr, size_t offset, size_t size);
167     angle::Result copyStagingTo(void *ptr, size_t offset, size_t size);
168     angle::Result copyStagingToFromWithPitch(void *ptr,
169                                              const cl::Coordinate &region,
170                                              const size_t rowPitch,
171                                              const size_t slicePitch,
172                                              StagingBufferCopyDirection copyStagingTo);
173     VkImageUsageFlags getVkImageUsageFlags();
174     VkImageType getVkImageType(const cl::ImageDescriptor &desc);
isStagingBufferInitialized()175     bool isStagingBufferInitialized() { return mStagingBufferInitialized; }
getImageExtent()176     cl::Extents getImageExtent() { return mExtent; }
getMappedPtr()177     uint8_t *getMappedPtr() { return mMappedMemory; }
getImageView()178     vk::ImageView &getImageView() { return mImageView; }
179     void packPixels(const void *fillColor, PixelColor *packedColor);
180     void fillImageWithColor(const cl::MemOffsets &origin,
181                             const cl::Coordinate &region,
182                             uint8_t *imagePtr,
183                             PixelColor *packedColor);
184     cl::Extents getExtentForCopy(const cl::Coordinate &region);
185     cl::Offset getOffsetForCopy(const cl::MemOffsets &origin);
186     VkImageSubresourceLayers getSubresourceLayersForCopy(const cl::MemOffsets &origin,
187                                                          const cl::Coordinate &region,
188                                                          cl::MemObjectType copyToType,
189                                                          ImageCopyWith imageCopy);
190 
191     angle::Result getBufferView(const vk::BufferView **viewOut);
192 
193   private:
194     angle::Result initImageViewImpl();
195 
196     angle::Result mapImpl() override;
197     void unmapImpl() override;
198     angle::Result setDataImpl(const uint8_t *data, size_t size, size_t offset);
199     size_t calculateRowPitch();
200     size_t calculateSlicePitch(size_t imageRowPitch);
201 
202     vk::ImageHelper mImage;
203     vk::BufferHelper mStagingBuffer;
204     cl::Extents mExtent;
205     angle::FormatID mAngleFormat;
206     bool mStagingBufferInitialized;
207     vk::ImageView mImageView;
208     VkImageViewType mImageViewType;
209 
210     // Images created from buffer create texel buffer views. BufferViewHelper contain the view
211     // corresponding to the attached buffer.
212     vk::BufferViewHelper mBufferViews;
213 };
214 
215 }  // namespace rx
216 
217 #endif  // LIBANGLE_RENDERER_VULKAN_CLMEMORYVK_H_
218