Skip to content

Commit 7fd0ccf

Browse files
authored
Merge pull request #17 from 420verfl0w/indev
merge dev to master
2 parents c7ad665 + b28b144 commit 7fd0ccf

36 files changed

+503
-154
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,20 @@
1313
###### MacroLibX, a rewrite of 42 School's MiniLibX using SDL2 and Vulkan.
1414
The goal of this version is to provide a light, fast, and modern graphical tool while keeping the same API.
1515

16+
## 💫 Features
17+
18+
### 🏁 Performances
19+
Built on top of Vulkan, the MacroLibX takes advantage of its very low-level nature to achieve high performance with great control over available resources.
20+
21+
### 💻 Cross-Platform
22+
Designed to be totally cross-platform, it can run on any SDL2-supported platform that supports Vulkan (even the Nintendo Switch ! theoretically... ).
23+
24+
### 🗿 Close to the old minilibx
25+
One of the guidelines of this lib was to get as close as possible to the old minilibx API, and therefore to the educational choices of the old minilibx.
26+
27+
### 📖 It's all FOSS
28+
Everything in this repo is entirely free and open source, all available under the MIT license (even the third-party libraries used).
29+
1630
## 🖥️ Installation
1731

1832
### Dependencies

includes/mlx.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
77
/* +#+#+#+#+#+ +#+ */
88
/* Created: 2022/10/04 16:56:35 by maldavid #+# #+# */
9-
/* Updated: 2023/12/11 20:35:41 by kbz_8 ### ########.fr */
9+
/* Updated: 2023/12/14 16:27:44 by maldavid ### ########.fr */
1010
/* */
1111
/* ************************************************************************** */
1212

@@ -282,7 +282,7 @@ MLX_API int mlx_string_put(void* mlx, void* win, int x, int y, int color, char*
282282
*
283283
* @param mlx Internal MLX application
284284
* @param win Internal window
285-
* @param filepath Filepath to the font
285+
* @param filepath Filepath to the font or "default" to reset to the embedded font
286286
*
287287
* @return (void)
288288
*/
@@ -293,7 +293,7 @@ MLX_API void mlx_set_font(void* mlx, void* win, char* filepath);
293293
*
294294
* @param mlx Internal MLX application
295295
* @param win Internal window
296-
* @param filepath Filepath to the font
296+
* @param filepath Filepath to the font or "default" to reset to the embedded font
297297
* @param scale Scale to apply to the font
298298
*
299299
* @return (void)

src/core/application.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
77
/* +#+#+#+#+#+ +#+ */
88
/* Created: 2022/10/04 22:10:52 by maldavid #+# #+# */
9-
/* Updated: 2023/12/11 19:46:13 by kbz_8 ### ########.fr */
9+
/* Updated: 2023/12/15 20:51:41 by maldavid ### ########.fr */
1010
/* */
1111
/* ************************************************************************** */
1212

@@ -61,7 +61,7 @@ namespace mlx::core
6161

6262
void Application::destroyTexture(void* ptr)
6363
{
64-
vkDeviceWaitIdle(Render_Core::get().getDevice().get());
64+
vkDeviceWaitIdle(Render_Core::get().getDevice().get()); // TODO : synchronize with another method than stopping all the GPU porcess
6565
Texture* texture = static_cast<Texture*>(ptr);
6666
texture->destroy();
6767
}

src/core/application.inl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,16 @@ namespace mlx::core
7474

7575
void Application::texturePut(void* win, void* img, int x, int y)
7676
{
77+
if(img == nullptr)
78+
{
79+
core::error::report(e_kind::error, "wrong texture (NULL)");
80+
return;
81+
}
7782
Texture* texture = static_cast<Texture*>(img);
78-
_graphics[*static_cast<int*>(win)]->texturePut(texture, x, y);
83+
if(!texture->isInit())
84+
core::error::report(e_kind::error, "trying to put a texture that has been destroyed");
85+
else
86+
_graphics[*static_cast<int*>(win)]->texturePut(texture, x, y);
7987
}
8088

8189
int Application::getTexturePixel(void* img, int x, int y)

src/core/bridge.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
77
/* +#+#+#+#+#+ +#+ */
88
/* Created: 2022/10/04 17:35:20 by maldavid #+# #+# */
9-
/* Updated: 2023/12/11 15:56:18 by kbz_8 ### ########.fr */
9+
/* Updated: 2023/12/14 17:47:17 by maldavid ### ########.fr */
1010
/* */
1111
/* ************************************************************************** */
1212

@@ -178,7 +178,7 @@ extern "C"
178178
void mlx_set_font(void* mlx, void* win, char* filepath)
179179
{
180180
std::filesystem::path file(filepath);
181-
if(file.extension() != ".ttf" && file.extension() != ".tte")
181+
if(std::strcmp(filepath, "default") != 0 && file.extension() != ".ttf" && file.extension() != ".tte")
182182
{
183183
mlx::core::error::report(e_kind::error, "TTF loader : not a truetype font file '%s'", filepath);
184184
return;
@@ -189,7 +189,7 @@ extern "C"
189189
void mlx_set_font_scale(void* mlx, void* win, char* filepath, float scale)
190190
{
191191
std::filesystem::path file(filepath);
192-
if(file.extension() != ".ttf" && file.extension() != ".tte")
192+
if(std::strcmp(filepath, "default") != 0 && file.extension() != ".ttf" && file.extension() != ".tte")
193193
{
194194
mlx::core::error::report(e_kind::error, "TTF loader : not a truetype font file '%s'", filepath);
195195
return;

src/core/graphics.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
77
/* +#+#+#+#+#+ +#+ */
88
/* Created: 2023/04/02 15:13:55 by maldavid #+# #+# */
9-
/* Updated: 2023/12/10 22:20:38 by kbz_8 ### ########.fr */
9+
/* Updated: 2023/12/15 21:04:50 by maldavid ### ########.fr */
1010
/* */
1111
/* ************************************************************************** */
1212

@@ -37,6 +37,8 @@ namespace mlx
3737

3838
for(auto& data : _textures_to_render)
3939
{
40+
if(!data.texture->isInit())
41+
continue;
4042
if(data.texture->getSet() == VK_NULL_HANDLE)
4143
data.texture->setDescriptor(_renderer->getFragDescriptorSet().duplicate());
4244
if(!data.texture->hasBeenUpdated())
@@ -51,11 +53,7 @@ namespace mlx
5153
sets[1] = _pixel_put_pipeline.getDescriptorSet();
5254
vkCmdBindDescriptorSets(cmd_buff, VK_PIPELINE_BIND_POINT_GRAPHICS, _renderer->getPipeline().getPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr);
5355
_pixel_put_pipeline.render(*_renderer);
54-
55-
sets[1] = _text_put_pipeline->getDescriptorSet();
56-
vkCmdBindDescriptorSets(cmd_buff, VK_PIPELINE_BIND_POINT_GRAPHICS, _renderer->getPipeline().getPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr);
57-
_text_put_pipeline->render();
58-
56+
_text_put_pipeline->render(sets);
5957
_renderer->endFrame();
6058

6159
for(auto& data : _textures_to_render)

src/core/graphics.inl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,7 @@ namespace mlx
4747
void GraphicsSupport::texturePut(Texture* texture, int x, int y)
4848
{
4949
_textures_to_render.emplace_back(texture, x, y);
50-
5150
auto it = std::find(_textures_to_render.begin(), _textures_to_render.end() - 1, _textures_to_render.back());
52-
5351
if(it != _textures_to_render.end() - 1)
5452
_textures_to_render.erase(it);
5553
}

src/renderer/buffers/vk_buffer.cpp

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
77
/* +#+#+#+#+#+ +#+ */
88
/* Created: 2022/10/08 18:55:57 by maldavid #+# #+# */
9-
/* Updated: 2023/12/10 23:05:14 by kbz_8 ### ########.fr */
9+
/* Updated: 2023/12/12 22:11:47 by kbz_8 ### ########.fr */
1010
/* */
1111
/* ************************************************************************** */
1212

@@ -23,9 +23,9 @@ namespace mlx
2323
void Buffer::create(Buffer::kind type, VkDeviceSize size, VkBufferUsageFlags usage, const char* name, const void* data)
2424
{
2525
_usage = usage;
26-
if(type == Buffer::kind::constant)
26+
if(type == Buffer::kind::constant || type == Buffer::kind::dynamic_device_local)
2727
{
28-
if(data == nullptr)
28+
if(data == nullptr && type == Buffer::kind::constant)
2929
{
3030
core::error::report(e_kind::warning, "Vulkan : trying to create constant buffer without data (constant buffers cannot be modified after creation)");
3131
return;
@@ -45,7 +45,7 @@ namespace mlx
4545
mapMem(&mapped);
4646
std::memcpy(mapped, data, size);
4747
unmapMem();
48-
if(type == Buffer::kind::constant)
48+
if(type == Buffer::kind::constant || type == Buffer::kind::dynamic_device_local)
4949
pushToGPU();
5050
}
5151
}
@@ -83,20 +83,20 @@ namespace mlx
8383
_size = size;
8484
}
8585

86-
void Buffer::pushToGPU() noexcept
86+
bool Buffer::copyFromBuffer(const Buffer& buffer) noexcept
8787
{
88-
VmaAllocationCreateInfo alloc_info{};
89-
alloc_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
90-
91-
Buffer newBuffer;
92-
newBuffer._usage = (_usage & 0xFFFFFFFC) | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
93-
#ifdef DEBUG
94-
std::string new_name = _name + "_GPU";
95-
newBuffer.createBuffer(newBuffer._usage, alloc_info, _size, new_name.c_str());
96-
#else
97-
newBuffer.createBuffer(newBuffer._usage, alloc_info, _size, nullptr);
98-
#endif
88+
if(!(_usage & VK_BUFFER_USAGE_TRANSFER_DST_BIT))
89+
{
90+
core::error::report(e_kind::error, "Vulkan : buffer cannot be the destination of a copy because it does not have the correct usage flag");
91+
return false;
92+
}
93+
if(!(buffer._usage & VK_BUFFER_USAGE_TRANSFER_SRC_BIT))
94+
{
95+
core::error::report(e_kind::error, "Vulkan : buffer cannot be the source of a copy because it does not have the correct usage flag");
96+
return false;
97+
}
9998

99+
// TODO, use global cmd buffer pool to manage resources
100100
CmdPool cmdpool;
101101
cmdpool.init();
102102
CmdBuffer cmdBuffer;
@@ -106,16 +106,33 @@ namespace mlx
106106

107107
VkBufferCopy copyRegion{};
108108
copyRegion.size = _size;
109-
vkCmdCopyBuffer(cmdBuffer.get(), _buffer, newBuffer._buffer, 1, &copyRegion);
109+
vkCmdCopyBuffer(cmdBuffer.get(), buffer._buffer, _buffer, 1, &copyRegion);
110110

111111
cmdBuffer.endRecord();
112112
cmdBuffer.submitIdle();
113113

114114
cmdBuffer.destroy();
115115
cmdpool.destroy();
116116

117-
this->swap(newBuffer);
117+
return true;
118+
}
119+
120+
void Buffer::pushToGPU() noexcept
121+
{
122+
VmaAllocationCreateInfo alloc_info{};
123+
alloc_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
124+
125+
Buffer newBuffer;
126+
newBuffer._usage = (_usage & 0xFFFFFFFC) | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
127+
#ifdef DEBUG
128+
std::string new_name = _name + "_GPU";
129+
newBuffer.createBuffer(newBuffer._usage, alloc_info, _size, new_name.c_str());
130+
#else
131+
newBuffer.createBuffer(newBuffer._usage, alloc_info, _size, nullptr);
132+
#endif
118133

134+
if(newBuffer.copyFromBuffer(*this)) // if the copy succeded we swap the buffers, else the new one is deleted
135+
this->swap(newBuffer);
119136
newBuffer.destroy();
120137
}
121138

src/renderer/buffers/vk_buffer.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
77
/* +#+#+#+#+#+ +#+ */
88
/* Created: 2022/10/06 23:18:52 by maldavid #+# #+# */
9-
/* Updated: 2023/12/11 19:47:39 by kbz_8 ### ########.fr */
9+
/* Updated: 2023/12/12 21:12:44 by kbz_8 ### ########.fr */
1010
/* */
1111
/* ************************************************************************** */
1212

@@ -22,7 +22,7 @@ namespace mlx
2222
class Buffer
2323
{
2424
public:
25-
enum class kind { dynamic, uniform, constant };
25+
enum class kind { dynamic, dynamic_device_local, uniform, constant };
2626

2727
void create(kind type, VkDeviceSize size, VkBufferUsageFlags usage, const char* name, const void* data = nullptr);
2828
void destroy() noexcept;
@@ -32,6 +32,7 @@ namespace mlx
3232
inline void unmapMem() noexcept { Render_Core::get().getAllocator().unmapMemory(_allocation); _is_mapped = false; }
3333

3434
void flush(VkDeviceSize size = VK_WHOLE_SIZE, VkDeviceSize offset = 0);
35+
bool copyFromBuffer(const Buffer& buffer) noexcept;
3536

3637
inline VkBuffer& operator()() noexcept { return _buffer; }
3738
inline VkBuffer& get() noexcept { return _buffer; }

src/renderer/buffers/vk_vbo.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
77
/* +#+#+#+#+#+ +#+ */
88
/* Created: 2022/10/06 18:28:08 by maldavid #+# #+# */
9-
/* Updated: 2023/11/10 08:33:52 by maldavid ### ########.fr */
9+
/* Updated: 2023/12/12 22:17:14 by kbz_8 ### ########.fr */
1010
/* */
1111
/* ************************************************************************** */
1212

@@ -18,7 +18,10 @@ namespace mlx
1818
void VBO::setData(uint32_t size, const void* data)
1919
{
2020
if(size > getSize())
21+
{
2122
core::error::report(e_kind::error, "Vulkan : trying to store to much data in a vertex buffer (%d bytes in %d bytes)", size, getSize());
23+
return;
24+
}
2225

2326
if(data == nullptr)
2427
core::error::report(e_kind::warning, "Vulkan : mapping null data in a vertex buffer");
@@ -28,4 +31,25 @@ namespace mlx
2831
std::memcpy(temp, data, static_cast<size_t>(size));
2932
unmapMem();
3033
}
34+
35+
void D_VBO::setData(uint32_t size, const void* data)
36+
{
37+
if(size > getSize())
38+
{
39+
core::error::report(e_kind::error, "Vulkan : trying to store to much data in a vertex buffer (%d bytes in %d bytes)", size, getSize());
40+
return;
41+
}
42+
43+
if(data == nullptr)
44+
core::error::report(e_kind::warning, "Vulkan : mapping null data in a vertex buffer");
45+
46+
Buffer tmp_buf;
47+
#ifdef DEBUG
48+
tmp_buf.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, "tmp_buffer", data);
49+
#else
50+
tmp_buf.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, nullptr, data);
51+
#endif
52+
copyFromBuffer(tmp_buf);
53+
tmp_buf.destroy();
54+
}
3155
}

src/renderer/buffers/vk_vbo.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
77
/* +#+#+#+#+#+ +#+ */
88
/* Created: 2022/10/06 18:27:38 by maldavid #+# #+# */
9-
/* Updated: 2023/12/08 19:06:45 by kbz_8 ### ########.fr */
9+
/* Updated: 2023/12/12 22:46:21 by kbz_8 ### ########.fr */
1010
/* */
1111
/* ************************************************************************** */
1212

@@ -22,7 +22,15 @@ namespace mlx
2222
class VBO : public Buffer
2323
{
2424
public:
25-
inline void create(uint32_t size, const char* name) { Buffer::create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, name); }
25+
inline void create(uint32_t size, const void* data, const char* name) { Buffer::create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, name, data); }
26+
void setData(uint32_t size, const void* data);
27+
inline void bind(Renderer& renderer) noexcept { vkCmdBindVertexBuffers(renderer.getActiveCmdBuffer().get(), 0, 1, &_buffer, &_offset); }
28+
};
29+
30+
class D_VBO : public Buffer
31+
{
32+
public:
33+
inline void create(uint32_t size, const void* data, const char* name) { Buffer::create(Buffer::kind::dynamic_device_local, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, name, data); }
2634
void setData(uint32_t size, const void* data);
2735
inline void bind(Renderer& renderer) noexcept { vkCmdBindVertexBuffers(renderer.getActiveCmdBuffer().get(), 0, 1, &_buffer, &_offset); }
2836
};
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/* ************************************************************************** */
2+
/* */
3+
/* ::: :::::::: */
4+
/* single_time_cmd_manager.cpp :+: :+: :+: */
5+
/* +:+ +:+ +:+ */
6+
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
7+
/* +#+#+#+#+#+ +#+ */
8+
/* Created: 2023/12/15 19:57:49 by maldavid #+# #+# */
9+
/* Updated: 2023/12/15 20:21:54 by maldavid ### ########.fr */
10+
/* */
11+
/* ************************************************************************** */
12+
13+
#include <algorithm>
14+
#include <renderer/command/single_time_cmd_manager.h>
15+
#include <renderer/core/render_core.h>
16+
17+
namespace mlx
18+
{
19+
SingleTimeCmdManager::SingleTimeCmdManager() : _buffers(MIN_POOL_SIZE) {}
20+
21+
void SingleTimeCmdManager::init() noexcept
22+
{
23+
_pool.init();
24+
for(int i = 0; i < MIN_POOL_SIZE; i++)
25+
_buffers.emplace_back().init(&_pool);
26+
}
27+
28+
void SingleTimeCmdManager::destroy() noexcept
29+
{
30+
std::for_each(_buffers.begin(), _buffers.end(), [](CmdBuffer& buf)
31+
{
32+
buf.destroy();
33+
});
34+
_pool.destroy();
35+
}
36+
37+
CmdBuffer& SingleTimeCmdManager::getCmdBuffer() noexcept
38+
{
39+
for(CmdBuffer& buf : _buffers)
40+
{
41+
if(buf.isReadyToBeUsed())
42+
return buf;
43+
}
44+
_buffers.emplace_back().init(&_pool);
45+
return _buffers.back();
46+
}
47+
}

0 commit comments

Comments
 (0)