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 ®ion, 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 ®ion, 190 uint8_t *imagePtr, 191 PixelColor *packedColor); 192 cl::Extents getExtentForCopy(const cl::Coordinate ®ion); 193 cl::Offset getOffsetForCopy(const cl::MemOffsets &origin); 194 VkImageSubresourceLayers getSubresourceLayersForCopy(const cl::MemOffsets &origin, 195 const cl::Coordinate ®ion, 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