• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     angle::Result copyToWithPitch(void *hostPtr,
104                                   size_t srcOffset,
105                                   size_t size,
106                                   size_t rowPitch,
107                                   size_t slicePitch,
108                                   cl::Coordinate region,
109                                   const size_t elementSize);
110 
fillWithPattern(const void * pattern,size_t patternSize,size_t offset,size_t size)111     angle::Result fillWithPattern(const void *pattern,
112                                   size_t patternSize,
113                                   size_t offset,
114                                   size_t size)
115     {
116         getBuffer().fillWithPattern(pattern, patternSize, getOffset() + offset, size);
117         return angle::Result::Continue;
118     }
119 
isSubBuffer()120     bool isSubBuffer() const { return mParent != nullptr; }
121 
122     angle::Result setRect(const void *data,
123                           const cl::BufferRect &srcRect,
124                           const cl::BufferRect &bufferRect);
125     angle::Result getRect(const cl::BufferRect &srcRect,
126                           const cl::BufferRect &outRect,
127                           void *outData);
128     std::vector<VkBufferCopy> rectCopyRegions(const cl::BufferRect &bufferRect);
129 
130     bool isCurrentlyInUse() const override;
getSize()131     size_t getSize() const override { return mMemory.getSize(); }
132 
133   private:
134     angle::Result mapImpl() override;
135     void unmapImpl() override;
136 
137     angle::Result setDataImpl(const uint8_t *data, size_t size, size_t offset);
138 
139     vk::BufferHelper mBuffer;
140     VkBufferCreateInfo mDefaultBufferCreateInfo;
141 };
142 
143 class CLImageVk : public CLMemoryVk
144 {
145   public:
146     CLImageVk(const cl::Image &image);
147     ~CLImageVk() override;
148 
getImage()149     vk::ImageHelper &getImage() { return mImage; }
getStagingBuffer()150     vk::BufferHelper &getStagingBuffer() { return mStagingBuffer; }
getFrontendObject()151     const cl::Image &getFrontendObject() const
152     {
153         return reinterpret_cast<const cl::Image &>(mMemory);
154     }
getFormat()155     cl_image_format getFormat() const { return getFrontendObject().getFormat(); }
getDescriptor()156     cl::ImageDescriptor getDescriptor() const { return getFrontendObject().getDescriptor(); }
getElementSize()157     size_t getElementSize() const { return getFrontendObject().getElementSize(); }
getArraySize()158     size_t getArraySize() const { return getFrontendObject().getArraySize(); }
getSize()159     size_t getSize() const override { return mMemory.getSize(); }
160     size_t getRowPitch() const;
161     size_t getSlicePitch() const;
162 
163     cl::MemObjectType getParentType() const;
164     template <typename T>
165     T *getParent() const;
166 
167     angle::Result create(void *hostPtr);
168     angle::Result createFromBuffer();
169 
170     bool isCurrentlyInUse() const override;
171     bool containsHostMemExtension();
172 
173     angle::Result createStagingBuffer(size_t size);
174     angle::Result copyStagingFrom(void *ptr, size_t offset, size_t size);
175     angle::Result copyStagingTo(void *ptr, size_t offset, size_t size);
176     angle::Result copyStagingToFromWithPitch(void *ptr,
177                                              const cl::Coordinate &region,
178                                              const size_t rowPitch,
179                                              const size_t slicePitch,
180                                              StagingBufferCopyDirection copyStagingTo);
181     VkImageUsageFlags getVkImageUsageFlags();
182     VkImageType getVkImageType(const cl::ImageDescriptor &desc);
isStagingBufferInitialized()183     bool isStagingBufferInitialized() { return mStagingBufferInitialized; }
getImageExtent()184     cl::Extents getImageExtent() { return mExtent; }
getMappedPtr()185     uint8_t *getMappedPtr() { return mMappedMemory; }
getImageView()186     vk::ImageView &getImageView() { return mImageView; }
187     void packPixels(const void *fillColor, PixelColor *packedColor);
188     void fillImageWithColor(const cl::MemOffsets &origin,
189                             const cl::Coordinate &region,
190                             uint8_t *imagePtr,
191                             PixelColor *packedColor);
192     cl::Extents getExtentForCopy(const cl::Coordinate &region);
193     cl::Offset getOffsetForCopy(const cl::MemOffsets &origin);
194     VkImageSubresourceLayers getSubresourceLayersForCopy(const cl::MemOffsets &origin,
195                                                          const cl::Coordinate &region,
196                                                          cl::MemObjectType copyToType,
197                                                          ImageCopyWith imageCopy);
198 
199     angle::Result getBufferView(const vk::BufferView **viewOut);
200 
201   private:
202     angle::Result initImageViewImpl();
203 
204     angle::Result mapImpl() override;
205     void unmapImpl() override;
206     angle::Result setDataImpl(const uint8_t *data, size_t size, size_t offset);
207     size_t calculateRowPitch();
208     size_t calculateSlicePitch(size_t imageRowPitch);
209 
210     vk::ImageHelper mImage;
211     vk::BufferHelper mStagingBuffer;
212     cl::Extents mExtent;
213     angle::FormatID mAngleFormat;
214     bool mStagingBufferInitialized;
215     vk::ImageView mImageView;
216     VkImageViewType mImageViewType;
217 
218     // Images created from buffer create texel buffer views. BufferViewHelper contain the view
219     // corresponding to the attached buffer.
220     vk::BufferViewHelper mBufferViews;
221 };
222 
223 }  // namespace rx
224 
225 #endif  // LIBANGLE_RENDERER_VULKAN_CLMEMORYVK_H_
226