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 ®ion, 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 ®ion, 182 uint8_t *imagePtr, 183 PixelColor *packedColor); 184 cl::Extents getExtentForCopy(const cl::Coordinate ®ion); 185 cl::Offset getOffsetForCopy(const cl::MemOffsets &origin); 186 VkImageSubresourceLayers getSubresourceLayersForCopy(const cl::MemOffsets &origin, 187 const cl::Coordinate ®ion, 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