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