nngn
Loading...
Searching...
No Matches
memory.h
Go to the documentation of this file.
1#ifndef NNGN_GRAPHICS_VULKAN_MEMORY_H
2#define NNGN_GRAPHICS_VULKAN_MEMORY_H
3
4#include <cstdint>
5#include <span>
6#include <type_traits>
7#include <vector>
8
9#include "graphics/graphics.h"
10#include "utils/log.h"
11
12#include "utils.h"
13#include "vulkan.h"
14
15namespace nngn {
16
17using MemoryAllocation = std::uint64_t;
18
21public:
23 static constexpr bool required(VkMemoryPropertyFlags f);
24 template<VkMemoryPropertyFlags f>
25 using find_ret = std::conditional_t<required(f), void, bool>;
27 DeviceMemory(void) = default;
28 ~DeviceMemory(void);
29 bool init(VkInstance inst, VkPhysicalDevice physical_dev, VkDevice dev);
36 template<VkMemoryPropertyFlags f>
37 find_ret<f> find_type(std::uint32_t type, std::uint32_t *p) const;
39 template<VkMemoryPropertyFlags f>
40 bool alloc(const VkMemoryRequirements *req, VkDeviceMemory *p);
45 template<VkMemoryPropertyFlags f>
46 bool alloc(
47 const VkMemoryRequirements *req, MemoryAllocation *alloc,
48 VkDeviceMemory *mem, VkDeviceSize *offset);
50 template<VkMemoryPropertyFlags f>
51 bool alloc(VkBuffer buf, VkDeviceMemory *p);
56 template<VkMemoryPropertyFlags f>
57 bool alloc(
59 VkDeviceMemory *mem, VkDeviceSize *offset);
61 template<VkMemoryPropertyFlags f>
62 bool alloc(VkImage img, VkDeviceMemory *p);
67 template<VkMemoryPropertyFlags f>
68 bool alloc(
70 VkDeviceMemory *mem, VkDeviceSize *offset);
72 void dealloc(VkDeviceMemory mem);
75private:
77 bool alloc(std::uint32_t type, VkDeviceSize size, VkDeviceMemory *p);
79 bool alloc(
80 std::uint32_t type, const VkMemoryRequirements *req,
81 MemoryAllocation *alloc, VkDeviceMemory *mem, VkDeviceSize *offset);
82 VkDevice dev = {};
83 void *allocator = {};
84 VkPhysicalDeviceMemoryProperties props = {};
85};
86
89 std::vector<Graphics::MemoryHeap> heaps = {};
90 std::vector<std::vector<Graphics::MemoryType>> memory_types = {};
91 void init(VkPhysicalDevice dev);
92};
93
94constexpr bool DeviceMemory::required(VkMemoryPropertyFlags f) {
95 constexpr auto device = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT;
96 constexpr auto host = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
97 | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
98 return f & device || (f & host) == host;
99}
100
101template<VkMemoryPropertyFlags f>
103 std::uint32_t type, std::uint32_t *p
104) const -> find_ret<f> {
105 constexpr auto ret = []([[maybe_unused]] auto b) {
106 if constexpr(!DeviceMemory::required(f))
107 return b;
108 };
109 for(std::uint32_t i = 0; i < this->props.memoryTypeCount; ++i) {
110 if(!(type & (std::uint32_t{1} << i)))
111 continue;
112 if((this->props.memoryTypes[i].propertyFlags & f) != f)
113 continue;
114 *p = i;
115 return ret(true);
116 }
118 Log::l() << "no suitable type found\n";
119 return ret(false);
120}
121
122template<VkMemoryPropertyFlags f>
124 const VkMemoryRequirements *req, VkDeviceMemory *p
125) {
126 std::uint32_t type = {};
127 if constexpr(DeviceMemory::required(f))
128 this->find_type<f>(req->memoryTypeBits, &type);
129 else if(!this->find_type<f>(req->memoryTypeBits, &type))
130 return false;
131 return this->alloc(type, req->size, p);
132}
133
134template<VkMemoryPropertyFlags f>
136 const VkMemoryRequirements *req, MemoryAllocation *alloc,
137 VkDeviceMemory *mem, VkDeviceSize *offset
138) {
139 std::uint32_t type = {};
140 if constexpr(DeviceMemory::required(f))
141 this->find_type<f>(req->memoryTypeBits, &type);
142 else if(!this->find_type<f>(req->memoryTypeBits, &type))
143 return false;
144 return this->alloc(type, req, alloc, mem, offset);
145}
146
147template<VkMemoryPropertyFlags f>
149 VkMemoryRequirements req;
150 vkGetBufferMemoryRequirements(this->dev, b, &req);
151 return this->alloc<f>(&req, p);
152}
153
154template<VkMemoryPropertyFlags f>
156 VkBuffer b, MemoryAllocation *alloc,
157 VkDeviceMemory *mem, VkDeviceSize *offset
158) {
159 VkMemoryRequirements req;
160 vkGetBufferMemoryRequirements(this->dev, b, &req);
161 return this->alloc<f>(&req, alloc, mem, offset);
162}
163
164template<VkMemoryPropertyFlags f>
166 VkMemoryRequirements req;
167 vkGetImageMemoryRequirements(this->dev, img, &req);
168 return this->alloc<f>(&req, p);
169}
170
171template<VkMemoryPropertyFlags f>
173 VkImage img, MemoryAllocation *alloc,
174 VkDeviceMemory *mem, VkDeviceSize *offset
175) {
176 VkMemoryRequirements req;
177 vkGetImageMemoryRequirements(this->dev, img, &req);
178 return this->alloc<f>(&req, alloc, mem, offset);
179}
180
181}
182
183#endif
Manages device memory queries, allocations, and lifetime.
Definition: memory.h:20
bool init(VkInstance inst, VkPhysicalDevice physical_dev, VkDevice dev)
Definition: memory.cpp:125
void dealloc(VkDeviceMemory mem)
Deallocates a block of device memory.
Definition: memory.cpp:155
static constexpr bool required(VkMemoryPropertyFlags f)
Indicates whether a memory type is guaranteed to exist.
Definition: memory.h:94
bool alloc(const VkMemoryRequirements *req, VkDeviceMemory *p)
Allocates device memory from a type that fulfills req.
Definition: memory.h:123
std::conditional_t< required(f), void, bool > find_ret
Definition: memory.h:25
void * allocator
Definition: memory.h:83
VkDevice dev
Definition: memory.h:82
VkPhysicalDeviceMemoryProperties props
Definition: memory.h:84
find_ret< f > find_type(std::uint32_t type, std::uint32_t *p) const
Finds a memory type among those offered by the device.
static std::ostream & l()
Definition: log.cpp:56
#define NNGN_LOG_CONTEXT_CF(c)
Definition: log.h:11
Definition: debug.h:45
COMMAND_BUFFER DESCRIPTOR_POOL DESCRIPTOR_SET_LAYOUT FENCE VkImage
Definition: types.h:71
COMMAND_BUFFER DESCRIPTOR_POOL DESCRIPTOR_SET_LAYOUT FENCE IMAGE PIPELINE PIPELINE_CACHE RENDER_PASS SEMAPHORE VkBuffer
Definition: types.h:77
std::uint64_t MemoryAllocation
Definition: memory.h:17
COMMAND_BUFFER DESCRIPTOR_POOL DESCRIPTOR_SET_LAYOUT FENCE IMAGE PIPELINE PIPELINE_CACHE RENDER_PASS SEMAPHORE BUFFER COMMAND_POOL DESCRIPTOR_SET VkDeviceMemory
Definition: types.h:77
Definition: debug.h:13
function f()) end
Aggregate type for information about a device's memory heaps.
Definition: memory.h:88
std::vector< Graphics::MemoryHeap > heaps
Definition: memory.h:89
std::vector< std::vector< Graphics::MemoryType > > memory_types
Definition: memory.h:90
void init(VkPhysicalDevice dev)
Definition: memory.cpp:160
#define NNGN_MOVE_ONLY(x)
Definition: utils.h:39