Skip to content

Commit 578fb71

Browse files
committed
feat, build: Use VMA library for memory allocation
1 parent 617843a commit 578fb71

10 files changed

Lines changed: 110 additions & 80 deletions

File tree

include/Game/Component/MeshRenderer.h

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,15 @@ namespace sh::game
1717
class MeshRenderer : public Component
1818
{
1919
SCLASS(MeshRenderer)
20-
private:
21-
struct alignas(16) Ubo
22-
{
23-
glm::mat4 model;
24-
glm::mat4 view;
25-
glm::mat4 proj;
26-
glm::vec3 offset;
27-
float offset2;
28-
} ubo;
2920
private:
3021
PROPERTY(mesh)
3122
sh::render::Mesh* mesh;
3223
PROPERTY(mat)
3324
sh::render::Material* mat;
34-
static std::unordered_map<sh::render::Mesh*, std::unique_ptr<sh::render::IDrawable>> drawables;
3525

36-
sh::render::IDrawable* drawable;
26+
std::unique_ptr<sh::render::IDrawable> drawable;
27+
28+
std::vector<unsigned char> uniformCopyData;
3729
private:
3830
void CreateDrawable();
3931
public:
@@ -50,6 +42,4 @@ namespace sh::game
5042
SH_GAME_API void Start() override;
5143
SH_GAME_API void Update() override;
5244
};
53-
54-
std::unordered_map<sh::render::Mesh*, std::unique_ptr<sh::render::IDrawable>> MeshRenderer::drawables{};
5545
}

include/Render/VulkanImpl/VulkanBuffer.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
#include "Core/NonCopyable.h"
88

9+
#include "../vma-src/include/vk_mem_alloc.h"
10+
911
namespace sh::render
1012
{
1113
namespace impl
@@ -15,24 +17,26 @@ namespace sh::render
1517
private:
1618
VkDevice device;
1719
VkPhysicalDevice gpu;
20+
VmaAllocator allocator;
21+
1822
VkBuffer buffer;
19-
VkDeviceMemory bufferMem;
23+
VmaAllocation bufferMem;
2024
VkBufferCreateInfo bufferInfo;
2125

2226
void* data;
2327
bool persistentMapping;
2428
private:
2529
auto FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties) -> uint32_t;
2630
public:
27-
SH_RENDER_API VulkanBuffer(VkDevice device, VkPhysicalDevice gpu);
31+
SH_RENDER_API VulkanBuffer(VkDevice device, VkPhysicalDevice gpu, VmaAllocator allocator);
2832
SH_RENDER_API VulkanBuffer(VulkanBuffer&& other) noexcept;
2933
SH_RENDER_API ~VulkanBuffer();
3034

3135
SH_RENDER_API auto Create(size_t size, VkBufferUsageFlags usageBits, VkSharingMode sharing, VkMemoryPropertyFlags memPropFlagBits, bool persistentMapping = false) -> VkResult;
3236
SH_RENDER_API void Clean();
3337
SH_RENDER_API void SetData(const void* data);
3438
SH_RENDER_API auto GetBuffer() const -> VkBuffer;
35-
SH_RENDER_API auto GetBufferMemory() const -> VkDeviceMemory;
39+
SH_RENDER_API auto GetBufferMemory() const -> VmaAllocation;
3640
};
3741
}
3842
}

include/Render/VulkanRenderer.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <Core/NonCopyable.h>
77
#include "VulkanImpl/VulkanConfig.h"
88

9+
#include "../vma-src/include/vk_mem_alloc.h"
910
#include "glm/mat4x4.hpp"
1011

1112
#include <string>
@@ -67,6 +68,8 @@ namespace sh::render {
6768
int currentFrame;
6869
uint32_t descriptorPoolSize;
6970

71+
VmaAllocator allocator;
72+
7073
bool isInit : 1;
7174
bool bPause : 1;
7275
bool bFindValidationLayer : 1;
@@ -100,6 +103,9 @@ namespace sh::render {
100103
auto CreateDescriptorPool() -> VkResult;
101104
void DestroyDescriptorPool();
102105

106+
void CreateAllocator();
107+
void DestroyAllocator();
108+
103109
void PrintLayer();
104110
public:
105111
SH_RENDER_API VulkanRenderer();
@@ -123,5 +129,6 @@ namespace sh::render {
123129
SH_RENDER_API auto GetCurrentFrame() const -> int;
124130
SH_RENDER_API auto GetWidth() const -> uint32_t override;
125131
SH_RENDER_API auto GetHeight() const -> uint32_t override;
132+
SH_RENDER_API auto GetAllocator() const -> VmaAllocator;
126133
};
127134
}//namespace

include/Window/Win32/WindowImplWin32.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@ namespace sh::window {
2222
auto Create(const std::string& title, int wsize, int hsize) -> WinHandle override;
2323
void Close() override;
2424
void ProcessEvent() override;
25+
void SetTitle(std::string_view title) override;
2526
};
2627
}

src/Game/Component/MeshRenderer.cpp

Lines changed: 12 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -51,27 +51,8 @@ namespace sh::game
5151
if (mesh == nullptr)
5252
return;
5353

54-
auto it = drawables.find(mesh);
55-
if (it == drawables.end())
56-
{
57-
gameObject.world.meshes.RegisterDestroyNotify(mesh, [&]() {
58-
drawables.erase(mesh);
59-
});
60-
61-
if (gameObject.world.renderer.apiType == sh::render::RenderAPI::Vulkan)
62-
{
63-
auto result = drawables.insert({mesh,
64-
std::make_unique<sh::render::VulkanDrawable>
65-
(static_cast<const sh::render::VulkanRenderer&>(gameObject.world.renderer))
66-
});
67-
68-
auto drawable = static_cast<sh::render::VulkanDrawable*>(result.first->second.get());
69-
drawable->Build(mat, mesh);
70-
this->drawable = drawable;
71-
}
72-
}
73-
else
74-
this->drawable = it->second.get();
54+
drawable = std::make_unique<sh::render::VulkanDrawable>(static_cast<render::VulkanRenderer&>(gameObject.world.renderer));
55+
drawable->Build(mat, mesh);
7556
}
7657

7758
void MeshRenderer::Awake()
@@ -100,45 +81,39 @@ namespace sh::game
10081
if (!sh::core::IsValid(cam))
10182
return;
10283

103-
ubo.proj = cam->GetProjMatrix();
104-
ubo.view = cam->GetViewMatrix();
105-
ubo.model = gameObject.transform->localToWorldMatrix;
106-
10784
sh::render::Renderer* renderer = &gameObject.world.renderer;
10885
if (renderer->apiType == sh::render::RenderAPI::Vulkan)
10986
{
110-
std::vector<unsigned char> data;
111-
11287
size_t size = mat->GetShader()->uniforms[0].back().offset + mat->GetShader()->uniforms[0].back().size;
113-
data.resize(size);
88+
uniformCopyData.resize(size);
11489
for (const auto& uniform : mat->GetShader()->uniforms[0])
11590
{
11691
if (uniform.typeName == sh::core::reflection::GetTypeName<glm::mat4>())
11792
{
11893
auto& m = cam->GetProjMatrix();
11994
if (uniform.name == "proj")
120-
std::memcpy(data.data() + uniform.offset, &cam->GetProjMatrix()[0], sizeof(glm::mat4));
95+
std::memcpy(uniformCopyData.data() + uniform.offset, &cam->GetProjMatrix()[0], sizeof(glm::mat4));
12196
else if (uniform.name == "view")
122-
std::memcpy(data.data() + uniform.offset, &cam->GetViewMatrix()[0], sizeof(glm::mat4));
97+
std::memcpy(uniformCopyData.data() + uniform.offset, &cam->GetViewMatrix()[0], sizeof(glm::mat4));
12398
else if (uniform.name == "model")
124-
std::memcpy(data.data() + uniform.offset, &gameObject.transform->localToWorldMatrix[0], sizeof(glm::mat4));
99+
std::memcpy(uniformCopyData.data() + uniform.offset, &gameObject.transform->localToWorldMatrix[0], sizeof(glm::mat4));
125100
}
126101
else if (uniform.typeName == sh::core::reflection::GetTypeName<glm::vec4>())
127-
std::memcpy(data.data() + uniform.offset, mat->GetVector(uniform.name), sizeof(glm::vec4));
102+
std::memcpy(uniformCopyData.data() + uniform.offset, mat->GetVector(uniform.name), sizeof(glm::vec4));
128103
else if (uniform.typeName == sh::core::reflection::GetTypeName<glm::vec3>())
129-
std::memcpy(data.data() + uniform.offset, mat->GetVector(uniform.name), sizeof(glm::vec3));
104+
std::memcpy(uniformCopyData.data() + uniform.offset, mat->GetVector(uniform.name), sizeof(glm::vec3));
130105
else if (uniform.typeName == sh::core::reflection::GetTypeName<glm::vec2>())
131-
std::memcpy(data.data() + uniform.offset, mat->GetVector(uniform.name), sizeof(glm::vec2));
106+
std::memcpy(uniformCopyData.data() + uniform.offset, mat->GetVector(uniform.name), sizeof(glm::vec2));
132107
else if (uniform.typeName == sh::core::reflection::GetTypeName<float>())
133108
{
134109
float value = mat->GetFloat(uniform.name);
135-
std::memcpy(data.data() + uniform.offset, &value, sizeof(float));
110+
std::memcpy(uniformCopyData.data() + uniform.offset, &value, sizeof(float));
136111
}
137112
}
138113

139114
int frameIdx = static_cast<sh::render::VulkanRenderer*>(renderer)->GetCurrentFrame();
140-
static_cast<sh::render::VulkanDrawable*>(drawable)->SetUniformData(frameIdx, data.data());
115+
static_cast<sh::render::VulkanDrawable*>(drawable.get())->SetUniformData(frameIdx, uniformCopyData.data());
141116
}
142-
gameObject.world.renderer.PushDrawAble(drawable);
117+
gameObject.world.renderer.PushDrawAble(drawable.get());
143118
}
144119
}

src/Render/CMakeLists.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,15 @@ FetchContent_Declare(
2929
FetchContent_MakeAvailable(GLM)
3030
target_link_libraries(ShellEngineRender PUBLIC glm)
3131

32+
FetchContent_Declare(
33+
VMA
34+
GIT_REPOSITORY "https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator"
35+
GIT_TAG "v3.0.1"
36+
)
37+
FetchContent_MakeAvailable(VMA)
38+
target_link_libraries(ShellEngineRender PRIVATE VulkanMemoryAllocator)
39+
3240
target_include_directories(ShellEngineRender PUBLIC ${Vulkan_INCLUDE_DIR})
3341
target_include_directories(ShellEngineRender PUBLIC ${CMAKE_SOURCE_DIR}/include)
3442
target_include_directories(ShellEngineRender PRIVATE ${CMAKE_SOURCE_DIR}/include/Render)
35-
target_include_directories(ShellEngineRender PRIVATE ${CMAKE_SOURCE_DIR}/include/Render/VulkanImpl)
43+
target_include_directories(ShellEngineRender PRIVATE ${CMAKE_SOURCE_DIR}/include/Render/VulkanImpl)

src/Render/VulkanDrawable.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace sh::render
1515
{
1616
VulkanDrawable::VulkanDrawable(const VulkanRenderer& renderer) :
1717
renderer(renderer),
18-
indexBuffer(renderer.GetDevice(), renderer.GetGPU()),
18+
indexBuffer(renderer.GetDevice(), renderer.GetGPU(), renderer.GetAllocator()),
1919
cmd(renderer.GetDevice(), renderer.GetCommandPool()),
2020
buffers(vertexBuffers),
2121
pipelineLayout(nullptr), mat(nullptr), mesh(nullptr),
@@ -68,7 +68,7 @@ namespace sh::render
6868
AddAttributeDescription(attrDesc);
6969

7070
size_t size = sizeof(glm::vec3) * mesh->GetVertexCount();
71-
impl::VulkanBuffer stagingBuffer1{ renderer.GetDevice(), renderer.GetGPU() };
71+
impl::VulkanBuffer stagingBuffer1{ renderer.GetDevice(), renderer.GetGPU(), renderer.GetAllocator() };
7272
stagingBuffer1.Create(size, VkBufferUsageFlagBits::VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
7373
VK_SHARING_MODE_EXCLUSIVE,
7474
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
@@ -80,7 +80,7 @@ namespace sh::render
8080
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
8181

8282
size_t sizeIndices = sizeof(uint32_t) * mesh->GetIndices().size();
83-
impl::VulkanBuffer stagingBuffer2{ renderer.GetDevice(), renderer.GetGPU() };
83+
impl::VulkanBuffer stagingBuffer2{ renderer.GetDevice(), renderer.GetGPU(), renderer.GetAllocator() };
8484
stagingBuffer2.Create(sizeIndices, VkBufferUsageFlagBits::VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
8585
VK_SHARING_MODE_EXCLUSIVE,
8686
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
@@ -157,7 +157,7 @@ namespace sh::render
157157
vertexBuffers.clear();
158158
indexBuffer.Clean();
159159

160-
vertexBuffers.push_back(impl::VulkanBuffer{ renderer.GetDevice(), renderer.GetGPU() });
160+
vertexBuffers.push_back(impl::VulkanBuffer{ renderer.GetDevice(), renderer.GetGPU(), renderer.GetAllocator() });
161161
CreateVertexBuffer();
162162
cmd.Clean();
163163

@@ -224,13 +224,13 @@ namespace sh::render
224224
AddBindingDescription(bindingDesc).
225225
AddAttributeDescription(attrDesc);
226226

227-
impl::VulkanBuffer stagingBuffer{ renderer.GetDevice(), renderer.GetGPU() };
227+
impl::VulkanBuffer stagingBuffer{ renderer.GetDevice(), renderer.GetGPU(), renderer.GetAllocator() };
228228
stagingBuffer.Create(size, VkBufferUsageFlagBits::VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
229229
VK_SHARING_MODE_EXCLUSIVE,
230230
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
231231
stagingBuffer.SetData(data);
232232

233-
vertexBuffers.push_back(impl::VulkanBuffer{renderer.GetDevice(), renderer.GetGPU()});
233+
vertexBuffers.push_back(impl::VulkanBuffer{renderer.GetDevice(), renderer.GetGPU(), renderer.GetAllocator() });
234234
vertexBuffers.back().Create(size,
235235
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
236236
VK_SHARING_MODE_EXCLUSIVE,
@@ -270,7 +270,7 @@ namespace sh::render
270270

271271
for (int i = 0; i < VulkanRenderer::MAX_FRAME_DRAW; ++i)
272272
{
273-
uniformBuffers.push_back(impl::VulkanBuffer{ renderer.GetDevice(), renderer.GetGPU() });
273+
uniformBuffers.push_back(impl::VulkanBuffer{ renderer.GetDevice(), renderer.GetGPU(), renderer.GetAllocator() });
274274
size_t size = mat->GetShader()->uniforms[0].back().offset + mat->GetShader()->uniforms[0].back().size;
275275
result = uniformBuffers.back().Create(size,
276276
VkBufferUsageFlagBits::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,

src/Render/VulkanImpl/VulkanBuffer.cpp

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
namespace sh::render::impl
88
{
9-
VulkanBuffer::VulkanBuffer(VkDevice device, VkPhysicalDevice gpu) :
10-
device(device), gpu(gpu),
9+
VulkanBuffer::VulkanBuffer(VkDevice device, VkPhysicalDevice gpu, VmaAllocator allocator) :
10+
device(device), gpu(gpu), allocator(allocator),
1111
buffer(nullptr), bufferMem(nullptr), data(nullptr),
1212
bufferInfo(),
1313
persistentMapping(false)
@@ -16,13 +16,14 @@ namespace sh::render::impl
1616
}
1717

1818
VulkanBuffer::VulkanBuffer(VulkanBuffer&& other) noexcept :
19-
device(other.device), gpu(other.gpu),
19+
device(other.device), gpu(other.gpu), allocator(other.allocator),
2020
buffer(other.buffer), bufferMem(other.bufferMem), data(other.data),
2121
bufferInfo(other.bufferInfo),
2222
persistentMapping(other.persistentMapping)
2323
{
2424
other.device = nullptr;
2525
other.gpu = nullptr;
26+
other.allocator = nullptr;
2627
other.buffer = nullptr;
2728
other.bufferMem = nullptr;
2829
other.data = nullptr;
@@ -37,15 +38,17 @@ namespace sh::render::impl
3738
{
3839
if (buffer)
3940
{
40-
vkDestroyBuffer(device, buffer, nullptr);
41+
vmaDestroyBuffer(allocator, buffer, bufferMem);
42+
//vkDestroyBuffer(device, buffer, nullptr);
4143
buffer = nullptr;
44+
bufferMem = nullptr;
4245
}
4346

44-
if (bufferMem)
47+
/*if (bufferMem)
4548
{
4649
vkFreeMemory(device, bufferMem, nullptr);
4750
bufferMem = nullptr;
48-
}
51+
}*/
4952
}
5053

5154
auto VulkanBuffer::FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties) -> uint32_t
@@ -71,7 +74,7 @@ namespace sh::render::impl
7174
bufferInfo.usage = usageBits;
7275
bufferInfo.sharingMode = sharing;
7376

74-
VkResult result = vkCreateBuffer(device, &bufferInfo, nullptr, &buffer);
77+
/*VkResult result = vkCreateBuffer(device, &bufferInfo, nullptr, &buffer);
7578
assert(result == VK_SUCCESS);
7679
if (result != VK_SUCCESS)
7780
return result;
@@ -86,16 +89,26 @@ namespace sh::render::impl
8689
allocInfo.allocationSize = memRequirements.size;
8790
allocInfo.memoryTypeIndex = idx;
8891
89-
result = vkAllocateMemory(device, &allocInfo, nullptr, &bufferMem);
90-
assert(result == VkResult::VK_SUCCESS);
91-
if (result != VK_SUCCESS)
92-
return result;
92+
result = vkAllocateMemory(device, &allocInfo, nullptr, &bufferMem);*/
93+
94+
bool bUseMap = (memPropFlagBits & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
9395

94-
result = vkBindBufferMemory(device, buffer, bufferMem, 0);
96+
VmaAllocationCreateInfo allocCreateInfo{};
97+
allocCreateInfo.usage = VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO;
98+
if (bUseMap)
99+
allocCreateInfo.flags = VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
100+
if (persistentMapping)
101+
allocCreateInfo.flags |= VmaAllocationCreateFlagBits::VMA_ALLOCATION_CREATE_MAPPED_BIT;
102+
103+
VmaAllocationInfo allocInfo{};
104+
auto result = vmaCreateBuffer(allocator, &bufferInfo, &allocCreateInfo, &buffer, &bufferMem, &allocInfo);
95105
assert(result == VkResult::VK_SUCCESS);
96-
if(persistentMapping)
97-
vkMapMemory(device, bufferMem, 0, bufferInfo.size, 0, &data);
98106

107+
if (persistentMapping)
108+
data = allocInfo.pMappedData;
109+
//result = vkBindBufferMemory(device, buffer, bufferMem, 0);
110+
//assert(result == VkResult::VK_SUCCESS);
111+
99112
return result;
100113
}
101114

@@ -107,9 +120,12 @@ namespace sh::render::impl
107120

108121
if (!persistentMapping)
109122
{
110-
vkMapMemory(device, bufferMem, 0, bufferInfo.size, 0, &this->data);
123+
//vkMapMemory(device, bufferMem, 0, bufferInfo.size, 0, &this->data);
124+
vmaMapMemory(allocator, bufferMem, &this->data);
111125
std::memcpy(this->data, data, static_cast<size_t>(bufferInfo.size));
112-
vkUnmapMemory(device, bufferMem);
126+
//vkUnmapMemory(device, bufferMem);
127+
vmaUnmapMemory(allocator, bufferMem);
128+
113129
}
114130
else
115131
std::memcpy(this->data, data, static_cast<size_t>(bufferInfo.size));
@@ -120,7 +136,7 @@ namespace sh::render::impl
120136
return buffer;
121137
}
122138

123-
auto VulkanBuffer::GetBufferMemory() const -> VkDeviceMemory
139+
auto VulkanBuffer::GetBufferMemory() const -> VmaAllocation
124140
{
125141
return bufferMem;
126142
}

0 commit comments

Comments
 (0)