1 /*
2 * Copyright (c) 2024 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_PLATFORM__
23 #include "../../../../../../../third_party/skia/third_party/vulkanmemoryallocator/include/vk_mem_alloc.h"
24 #else
25 #include <VulkanMemoryAllocator/src/vk_mem_alloc.h>
26 #endif
27 // clang-format on
28 #include <cstddef>
29 #include <cstdint>
30
31 #include <base/containers/string.h>
32 #include <base/containers/unordered_map.h>
33 #include <base/containers/vector.h>
34 #include <render/device/gpu_resource_desc.h>
35 #include <render/namespace.h>
36
RENDER_BEGIN_NAMESPACE()37 RENDER_BEGIN_NAMESPACE()
38 /** Gpu memory allocator.
39 * Wrapper around Vulkan Memory Allocator (GPU Open) which is internally synchronized.
40 */
41 class PlatformGpuMemoryAllocator final {
42 public:
43 enum class MemoryAllocatorResourceType : uint8_t {
44 UNDEFINED = 0, // not supported ATM, needs to be buffer or image
45 GPU_BUFFER = 1,
46 GPU_IMAGE = 2,
47 };
48 struct GpuMemoryAllocatorCustomPool {
49 BASE_NS::string name;
50
51 MemoryAllocatorResourceType resourceType { MemoryAllocatorResourceType::UNDEFINED };
52 uint32_t blockSize { 0 }; // zero fallbacks to default
53 bool linearAllocationAlgorithm { false };
54
55 union GpuResourceDesc {
56 GpuBufferDesc buffer;
57 GpuImageDesc image;
58 };
59 GpuResourceDesc gpuResourceDesc;
60 };
61
62 struct GpuMemoryAllocatorCreateInfo {
63 // set to zero for default (vma default 256 MB)
64 uint32_t preferredLargeHeapBlockSize { 32 * 1024 * 1024 };
65
66 BASE_NS::vector<GpuMemoryAllocatorCustomPool> customPools;
67 };
68
69 PlatformGpuMemoryAllocator(VkInstance instance, VkPhysicalDevice physicalDevice, VkDevice device,
70 const GpuMemoryAllocatorCreateInfo& createInfo);
71 ~PlatformGpuMemoryAllocator();
72
73 void CreateBuffer(const VkBufferCreateInfo& bufferCreateInfo, const VmaAllocationCreateInfo& allocationCreateInfo,
74 VkBuffer& buffer, VmaAllocation& allocation, VmaAllocationInfo& allocationInfo);
75 void DestroyBuffer(VkBuffer buffer, VmaAllocation allocation);
76
77 void CreateImage(const VkImageCreateInfo& imageCreateInfo, const VmaAllocationCreateInfo& allocationCreateInfo,
78 VkImage& image, VmaAllocation& allocation, VmaAllocationInfo& allocationInfo);
79 void DestroyImage(VkImage image, VmaAllocation allocation);
80
81 void* MapMemory(VmaAllocation allocation);
82 void UnmapMemory(VmaAllocation allocation);
83
84 void FlushAllocation(const VmaAllocation& allocation, const VkDeviceSize offset, const VkDeviceSize byteSize);
85 void InvalidateAllocation(const VmaAllocation& allocation, const VkDeviceSize offset, const VkDeviceSize byteSize);
86 uint32_t GetMemoryTypeProperties(const uint32_t memoryType);
87
88 VmaPool GetBufferPool(const GpuBufferDesc& desc) const;
89 VmaPool GetImagePool(const GpuImageDesc& desc) const;
90
91 #if defined(RENDER_PERF_ENABLED) && (RENDER_PERF_ENABLED == 1)
92 BASE_NS::string GetBufferPoolDebugName(const GpuBufferDesc& desc) const;
93 BASE_NS::string GetImagePoolDebugName(const GpuImageDesc& desc) const;
94 #endif
95
96 private:
97 void CreatePoolForBuffers(const GpuMemoryAllocatorCustomPool& customPool);
98 void CreatePoolForImages(const GpuMemoryAllocatorCustomPool& customPool);
99 VmaAllocator allocator_ {};
100
101 BASE_NS::vector<VmaPool> customGpuBufferPools_;
102 BASE_NS::vector<VmaPool> customGpuImagePools_;
103
104 BASE_NS::unordered_map<uint64_t, uint32_t> hashToGpuBufferPoolIndex_;
105 BASE_NS::unordered_map<uint64_t, uint32_t> hashToGpuImagePoolIndex_;
106
107 #if defined(RENDER_PERF_ENABLED) && (RENDER_PERF_ENABLED == 1)
108 BASE_NS::vector<BASE_NS::string> customGpuBufferPoolNames_;
109 BASE_NS::vector<BASE_NS::string> customGpuImagePoolNames_;
110
111 struct MemoryDebugStruct {
112 uint64_t buffer { 0 };
113 uint64_t image { 0 };
114 };
115 MemoryDebugStruct memoryDebugStruct_;
116 #endif
117 };
118 RENDER_END_NAMESPACE()
119
120 #endif // VULKAN_GPU_MEMORY_ALLOCATOR_VK_H
121