1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef VULKAN_GPU_MEMORY_ALLOCATOR_VK_H
17 #define VULKAN_GPU_MEMORY_ALLOCATOR_VK_H
18
19 // vulkan_core must be before vk_mem_alloc
20 // clang-format off
21 #include <vulkan/vulkan_core.h>
22 #ifdef __OHOS__
23 #ifdef USE_M133_SKIA
24 #include <third_party/externals/vulkanmemoryallocator/include/vk_mem_alloc.h>
25 #else
26 #include <third_party/vulkanmemoryallocator/include/vk_mem_alloc.h>
27 #endif
28 #else
29 #include <VulkanMemoryAllocator/src/vk_mem_alloc.h>
30 #endif
31 // clang-format on
32 #include <cstddef>
33 #include <cstdint>
34
35 #include <base/containers/string.h>
36 #include <base/containers/unordered_map.h>
37 #include <base/containers/vector.h>
38 #include <render/device/gpu_resource_desc.h>
39 #include <render/namespace.h>
40
RENDER_BEGIN_NAMESPACE()41 RENDER_BEGIN_NAMESPACE()
42 /** Gpu memory allocator.
43 * Wrapper around Vulkan Memory Allocator (GPU Open) which is internally synchronized.
44 */
45 class PlatformGpuMemoryAllocator final {
46 public:
47 enum class MemoryAllocatorResourceType : uint8_t {
48 UNDEFINED = 0, // not supported ATM, needs to be buffer or image
49 GPU_BUFFER = 1,
50 GPU_IMAGE = 2,
51 };
52 struct GpuMemoryAllocatorCustomPool {
53 BASE_NS::string name;
54
55 MemoryAllocatorResourceType resourceType { MemoryAllocatorResourceType::UNDEFINED };
56 uint32_t blockSize { 0 }; // zero fallbacks to default
57 bool linearAllocationAlgorithm { false };
58
59 union GpuResourceDesc {
60 GpuBufferDesc buffer;
61 GpuImageDesc image;
62 };
63 GpuResourceDesc gpuResourceDesc;
64 };
65
66 struct GpuMemoryAllocatorCreateInfo {
67 // set to zero for default (vma default 256 MB)
68 uint32_t preferredLargeHeapBlockSize { 32 * 1024 * 1024 };
69
70 enum CreateInfoFlagBits : uint32_t {
71 ENABLE_DEVICE_ADDRESSES_BIT = (1 << 0),
72 };
73 using CreateInfoFlags = uint32_t;
74
75 CreateInfoFlags createFlags { 0U };
76 BASE_NS::vector<GpuMemoryAllocatorCustomPool> customPools;
77 };
78
79 PlatformGpuMemoryAllocator(VkInstance instance, VkPhysicalDevice physicalDevice, VkDevice device,
80 const GpuMemoryAllocatorCreateInfo& createInfo);
81 ~PlatformGpuMemoryAllocator();
82
83 void CreateBuffer(const VkBufferCreateInfo& bufferCreateInfo, const VmaAllocationCreateInfo& allocationCreateInfo,
84 VkBuffer& buffer, VmaAllocation& allocation, VmaAllocationInfo& allocationInfo);
85 void DestroyBuffer(VkBuffer buffer, VmaAllocation allocation);
86
87 void CreateImage(const VkImageCreateInfo& imageCreateInfo, const VmaAllocationCreateInfo& allocationCreateInfo,
88 VkImage& image, VmaAllocation& allocation, VmaAllocationInfo& allocationInfo);
89 void DestroyImage(VkImage image, VmaAllocation allocation);
90
91 void* MapMemory(VmaAllocation allocation);
92 void UnmapMemory(VmaAllocation allocation);
93
94 void FlushAllocation(const VmaAllocation& allocation, VkDeviceSize offset, VkDeviceSize byteSize);
95 void InvalidateAllocation(const VmaAllocation& allocation, VkDeviceSize offset, VkDeviceSize byteSize);
96 uint32_t GetMemoryTypeProperties(uint32_t memoryType);
97
98 VmaPool GetBufferPool(const GpuBufferDesc& desc) const;
99 VmaPool GetImagePool(const GpuImageDesc& desc) const;
100
101 #if defined(RENDER_PERF_ENABLED) && (RENDER_PERF_ENABLED == 1)
102 BASE_NS::string GetBufferPoolDebugName(const GpuBufferDesc& desc) const;
103 BASE_NS::string GetImagePoolDebugName(const GpuImageDesc& desc) const;
104 #endif
105
106 private:
107 void CreatePoolForBuffers(const GpuMemoryAllocatorCustomPool& customPool);
108 void CreatePoolForImages(const GpuMemoryAllocatorCustomPool& customPool);
109 VmaAllocator allocator_ {};
110
111 BASE_NS::vector<VmaPool> customGpuBufferPools_;
112 BASE_NS::vector<VmaPool> customGpuImagePools_;
113
114 BASE_NS::unordered_map<uint64_t, uint32_t> hashToGpuBufferPoolIndex_;
115 BASE_NS::unordered_map<uint64_t, uint32_t> hashToGpuImagePoolIndex_;
116
117 #if defined(RENDER_PERF_ENABLED) && (RENDER_PERF_ENABLED == 1)
118 BASE_NS::vector<BASE_NS::string> customGpuBufferPoolNames_;
119 BASE_NS::vector<BASE_NS::string> customGpuImagePoolNames_;
120
121 struct MemoryDebugStruct {
122 uint64_t buffer { 0 };
123 uint64_t image { 0 };
124 };
125 MemoryDebugStruct memoryDebugStruct_;
126 #endif
127 };
128 RENDER_END_NAMESPACE()
129
130 #endif // VULKAN_GPU_MEMORY_ALLOCATOR_VK_H
131