// // Copyright 2021 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // // CLMemoryVk.h: Defines the class interface for CLMemoryVk, implementing CLMemoryImpl. #ifndef LIBANGLE_RENDERER_VULKAN_CLMEMORYVK_H_ #define LIBANGLE_RENDERER_VULKAN_CLMEMORYVK_H_ #include "common/PackedCLEnums_autogen.h" #include "common/SimpleMutex.h" #include "libANGLE/renderer/vulkan/cl_types.h" #include "libANGLE/renderer/vulkan/vk_helpers.h" #include "libANGLE/renderer/CLMemoryImpl.h" #include "libANGLE/CLBuffer.h" #include "libANGLE/CLImage.h" #include "libANGLE/CLMemory.h" #include "libANGLE/renderer/vulkan/vk_wrapper.h" #include "vulkan/vulkan_core.h" namespace rx { union PixelColor { uint8_t u8[4]; int8_t s8[4]; uint16_t u16[4]; int16_t s16[4]; uint32_t u32[4]; int32_t s32[4]; cl_half fp16[4]; cl_float fp32[4]; }; class CLMemoryVk : public CLMemoryImpl { public: ~CLMemoryVk() override; // TODO: http://anglebug.com/42267017 angle::Result createSubBuffer(const cl::Buffer &buffer, cl::MemFlags flags, size_t size, CLMemoryImpl::Ptr *subBufferOut) override; angle::Result map(uint8_t *&ptrOut, size_t offset = 0); void unmap() { unmapImpl(); } VkBufferUsageFlags getVkUsageFlags(); VkMemoryPropertyFlags getVkMemPropertyFlags(); virtual size_t getSize() const = 0; size_t getOffset() const { return mMemory.getOffset(); } cl::MemFlags getFlags() const { return mMemory.getFlags(); } cl::MemObjectType getType() const { return mMemory.getType(); } angle::Result copyTo(void *ptr, size_t offset, size_t size); angle::Result copyTo(CLMemoryVk *dst, size_t srcOffset, size_t dstOffset, size_t size); angle::Result copyFrom(const void *ptr, size_t offset, size_t size); bool isWritable() { constexpr VkBufferUsageFlags kWritableUsage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; return (getVkUsageFlags() & kWritableUsage) != 0; } virtual bool isCurrentlyInUse() const = 0; bool isMapped() const { return mMappedMemory != nullptr; } protected: CLMemoryVk(const cl::Memory &memory); virtual angle::Result mapImpl() = 0; virtual void unmapImpl() = 0; CLContextVk *mContext; vk::Renderer *mRenderer; vk::Allocation mAllocation; angle::SimpleMutex mMapLock; uint8_t *mMappedMemory; uint32_t mMapCount; CLMemoryVk *mParent; }; class CLBufferVk : public CLMemoryVk { public: CLBufferVk(const cl::Buffer &buffer); ~CLBufferVk() override; vk::BufferHelper &getBuffer(); CLBufferVk *getParent() { return static_cast(mParent); } const cl::Buffer &getFrontendObject() { return reinterpret_cast(mMemory); } angle::Result create(void *hostPtr); angle::Result createStagingBuffer(size_t size); angle::Result copyToWithPitch(void *hostPtr, size_t srcOffset, size_t size, size_t rowPitch, size_t slicePitch, cl::Coordinate region, const size_t elementSize); angle::Result fillWithPattern(const void *pattern, size_t patternSize, size_t offset, size_t size) { getBuffer().fillWithPattern(pattern, patternSize, getOffset() + offset, size); return angle::Result::Continue; } bool isSubBuffer() const { return mParent != nullptr; } angle::Result setRect(const void *data, const cl::BufferRect &srcRect, const cl::BufferRect &bufferRect); angle::Result getRect(const cl::BufferRect &srcRect, const cl::BufferRect &outRect, void *outData); std::vector rectCopyRegions(const cl::BufferRect &bufferRect); bool isCurrentlyInUse() const override; size_t getSize() const override { return mMemory.getSize(); } private: angle::Result mapImpl() override; void unmapImpl() override; angle::Result setDataImpl(const uint8_t *data, size_t size, size_t offset); vk::BufferHelper mBuffer; VkBufferCreateInfo mDefaultBufferCreateInfo; }; class CLImageVk : public CLMemoryVk { public: CLImageVk(const cl::Image &image); ~CLImageVk() override; vk::ImageHelper &getImage() { return mImage; } vk::BufferHelper &getStagingBuffer() { return mStagingBuffer; } const cl::Image &getFrontendObject() const { return reinterpret_cast(mMemory); } cl_image_format getFormat() const { return getFrontendObject().getFormat(); } cl::ImageDescriptor getDescriptor() const { return getFrontendObject().getDescriptor(); } size_t getElementSize() const { return getFrontendObject().getElementSize(); } size_t getArraySize() const { return getFrontendObject().getArraySize(); } size_t getSize() const override { return mMemory.getSize(); } size_t getRowPitch() const; size_t getSlicePitch() const; cl::MemObjectType getParentType() const; template T *getParent() const; angle::Result create(void *hostPtr); angle::Result createFromBuffer(); bool isCurrentlyInUse() const override; bool containsHostMemExtension(); angle::Result createStagingBuffer(size_t size); angle::Result copyStagingFrom(void *ptr, size_t offset, size_t size); angle::Result copyStagingTo(void *ptr, size_t offset, size_t size); angle::Result copyStagingToFromWithPitch(void *ptr, const cl::Coordinate ®ion, const size_t rowPitch, const size_t slicePitch, StagingBufferCopyDirection copyStagingTo); VkImageUsageFlags getVkImageUsageFlags(); VkImageType getVkImageType(const cl::ImageDescriptor &desc); bool isStagingBufferInitialized() { return mStagingBufferInitialized; } cl::Extents getImageExtent() { return mExtent; } uint8_t *getMappedPtr() { return mMappedMemory; } vk::ImageView &getImageView() { return mImageView; } void packPixels(const void *fillColor, PixelColor *packedColor); void fillImageWithColor(const cl::MemOffsets &origin, const cl::Coordinate ®ion, uint8_t *imagePtr, PixelColor *packedColor); cl::Extents getExtentForCopy(const cl::Coordinate ®ion); cl::Offset getOffsetForCopy(const cl::MemOffsets &origin); VkImageSubresourceLayers getSubresourceLayersForCopy(const cl::MemOffsets &origin, const cl::Coordinate ®ion, cl::MemObjectType copyToType, ImageCopyWith imageCopy); angle::Result getBufferView(const vk::BufferView **viewOut); private: angle::Result initImageViewImpl(); angle::Result mapImpl() override; void unmapImpl() override; angle::Result setDataImpl(const uint8_t *data, size_t size, size_t offset); size_t calculateRowPitch(); size_t calculateSlicePitch(size_t imageRowPitch); vk::ImageHelper mImage; vk::BufferHelper mStagingBuffer; cl::Extents mExtent; angle::FormatID mAngleFormat; bool mStagingBufferInitialized; vk::ImageView mImageView; VkImageViewType mImageViewType; // Images created from buffer create texel buffer views. BufferViewHelper contain the view // corresponding to the attached buffer. vk::BufferViewHelper mBufferViews; }; } // namespace rx #endif // LIBANGLE_RENDERER_VULKAN_CLMEMORYVK_H_