merge indev to master (#20)

This commit is contained in:
kbz_8
2023-12-20 17:50:38 +01:00
committed by GitHub
18 changed files with 205 additions and 103 deletions

View File

@@ -13,9 +13,9 @@
###### MacroLibX, a rewrite of 42 School's MiniLibX using SDL2 and Vulkan.
The goal of this version is to provide a light, fast, and modern graphical tool while keeping the same API.
## πŸ’« Features
## 🌟 Features
### 🏁 Performances
### πŸš€ Performances
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.
### πŸ’» Cross-Platform
@@ -27,6 +27,12 @@ One of the guidelines of this lib was to get as close as possible to the old min
### πŸ“– It's all FOSS
Everything in this repo is entirely free and open source, all available under the MIT license (even the third-party libraries used).
### πŸ” Valgrind suppressions file
Experimental for now, a [suppressions file for valgrind](./valgrind.supp) is given to remove potential leaks comming from Xorg, Nvidia drivers, SDL2, or any other tool which the user has no control. It is far from perfect at the moment and may allow some leaks but it will block the majority.
### β›” Error system
Strong error handling informing the user of problems with their code and even capable of informing them of graphics memory leaks that tools like Valgrind cannot detect.
## πŸ–₯️ Installation
### Dependencies
@@ -101,5 +107,4 @@ You can force the mlx to use your integrated GPU by using `make FORCE_INTEGRATED
The mlx can dump it's graphics memory use to json files every two seconds by enabling this option `make GRAPHICS_MEMORY_DUMP=true`.
## License
This project and all its files, except the [`third_party`](./third_party) directory or unless otherwise mentionned, are licenced under the [MIT license](./LICENSE).
This project and all its files, even the [`third_party`](./third_party) directory or unless otherwise mentionned, are licenced under the [MIT license](./LICENSE).

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/11/10 08:49:17 by maldavid #+# #+# */
/* Updated: 2023/12/11 20:35:57 by kbz_8 ### ########.fr */
/* Updated: 2023/12/16 20:20:35 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -50,19 +50,49 @@
#elif defined(unix) || defined(__unix__) || defined(__unix)
#define MLX_PLAT_UNIX
#else
#error "Unknown environment!"
#error "Unknown environment (not Windows, not Linux, not MacOS, not Unix)"
#endif
#ifdef MLX_COMPILER_MSVC
#ifdef MLX_BUILD
#define MLX_API __declspec(dllexport)
#ifdef MLX_PLAT_WINDOWS
#ifdef MLX_COMPILER_MSVC
#ifdef MLX_BUILD
#define MLX_API __declspec(dllexport)
#else
#define MLX_API __declspec(dllimport)
#endif
#elif defined(MLX_COMPILER_GCC)
#ifdef MLX_BUILD
#define MLX_API __attribute__((dllexport))
#else
#define MLX_API __attribute__((dllimport))
#endif
#else
#define MLX_API __declspec(dllimport)
#define MLX_API
#endif
#elif defined(MLX_COMPILER_GCC)
#define MLX_API __attribute__((visibility("default")))
#else
#define MLX_API
#endif
#if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__)
#define MLX_FUNC_SIG __PRETTY_FUNCTION__
#elif defined(__DMC__) && (__DMC__ >= 0x810)
#define MLX_FUNC_SIG __PRETTY_FUNCTION__
#elif (defined(__FUNCSIG__) || (_MSC_VER))
#define MLX_FUNC_SIG __FUNCSIG__
#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500))
#define MLX_FUNC_SIG __FUNCTION__
#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)
#define MLX_FUNC_SIG __FUNC__
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
#define MLX_FUNC_SIG __func__
#elif defined(__cplusplus) && (__cplusplus >= 201103)
#define MLX_FUNC_SIG __func__
#else
#define MLX_FUNC_SIG "Unknown function"
#endif
// Checking common assumptions
#ifdef __cplusplus
#include <climits>

View File

@@ -88,14 +88,32 @@ namespace mlx::core
int Application::getTexturePixel(void* img, int x, int y)
{
if(img == nullptr)
{
core::error::report(e_kind::error, "wrong texture (NULL)");
return 0;
}
Texture* texture = static_cast<Texture*>(img);
if(!texture->isInit())
{
core::error::report(e_kind::error, "trying to get a pixel from texture that has been destroyed");
return 0;
}
return texture->getPixel(x, y);
}
void Application::setTexturePixel(void* img, int x, int y, uint32_t color)
{
if(img == nullptr)
{
core::error::report(e_kind::error, "wrong texture (NULL)");
return;
}
Texture* texture = static_cast<Texture*>(img);
texture->setPixel(x, y, color);
if(!texture->isInit())
core::error::report(e_kind::error, "trying to set a pixel on texture that has been destroyed");
else
texture->setPixel(x, y, color);
}
void Application::loopHook(int (*f)(void*), void* param)

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/04 17:35:20 by maldavid #+# #+# */
/* Updated: 2023/12/14 17:47:17 by maldavid ### ########.fr */
/* Updated: 2023/12/16 20:20:41 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -17,13 +17,20 @@
#include <filesystem>
#include <mlx.h>
#include <core/memory.h>
#include <mlx_profile.h>
static void* __mlx_ptr = nullptr;
#define MLX_CHECK_APPLICATION_POINTER(ptr) \
if(ptr != __mlx_ptr || ptr == NULL) \
mlx::core::error::report(e_kind::fatal_error, "invalid mlx pointer passed to '%s'", MLX_FUNC_SIG); \
else {} // just to avoid issues with possible if-else statements outside this macro
extern "C"
{
void* mlx_init()
{
static bool init = false;
if(init)
if(__mlx_ptr != nullptr)
{
mlx::core::error::report(e_kind::error, "MLX cannot be initialized multiple times");
return NULL; // not nullptr for the C compatibility
@@ -33,29 +40,33 @@ extern "C"
mlx::Render_Core::get().init();
if(app == nullptr)
mlx::core::error::report(e_kind::fatal_error, "Tout a pΓ©tΓ©");
init = true;
return static_cast<void*>(app);
__mlx_ptr = static_cast<void*>(app);
return __mlx_ptr;
}
void* mlx_new_window(void* mlx, int w, int h, const char* title)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
return static_cast<mlx::core::Application*>(mlx)->newGraphicsSuport(w, h, title);
}
int mlx_loop_hook(void* mlx, int (*f)(void*), void* param)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
static_cast<mlx::core::Application*>(mlx)->loopHook(f, param);
return 0;
}
int mlx_loop(void* mlx)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
static_cast<mlx::core::Application*>(mlx)->run();
return 0;
}
int mlx_loop_end(void* mlx)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
static_cast<mlx::core::Application*>(mlx)->loopEnd();
return 0;
}
@@ -72,34 +83,40 @@ extern "C"
int mlx_mouse_move(void* mlx, void* win, int x, int y)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
static_cast<mlx::core::Application*>(mlx)->mouseMove(win, x, y);
return 0;
}
int mlx_mouse_get_pos(void* mlx, int* x, int* y)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
static_cast<mlx::core::Application*>(mlx)->getMousePos(x, y);
return 0;
}
int mlx_on_event(void* mlx, void* win, mlx_event_type event, int (*funct_ptr)(int, void*), void* param)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
static_cast<mlx::core::Application*>(mlx)->onEvent(win, static_cast<int>(event), funct_ptr, param);
return 0;
}
void* mlx_new_image(void* mlx, int width, int height)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
return static_cast<mlx::core::Application*>(mlx)->newTexture(width, height);
}
int mlx_get_image_pixel(void* mlx, void* img, int x, int y)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
return static_cast<mlx::core::Application*>(mlx)->getTexturePixel(img, x, y);
}
void mlx_set_image_pixel(void* mlx, void* img, int x, int y, int color)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
unsigned char color_bits[4];
color_bits[0] = (color & 0x00FF0000) >> 16;
color_bits[1] = (color & 0x0000FF00) >> 8;
@@ -110,18 +127,21 @@ extern "C"
int mlx_put_image_to_window(void* mlx, void* win, void* img, int x, int y)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
static_cast<mlx::core::Application*>(mlx)->texturePut(win, img, x, y);
return 0;
}
int mlx_destroy_image(void* mlx, void* img)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
static_cast<mlx::core::Application*>(mlx)->destroyTexture(img);
return 0;
}
void* mlx_png_file_to_image(void* mlx, char* filename, int* width, int* height)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
std::filesystem::path file(filename);
if(file.extension() != ".png")
{
@@ -133,6 +153,7 @@ extern "C"
void* mlx_jpg_file_to_image(void* mlx, char* filename, int* width, int* height)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
std::filesystem::path file(filename);
if(file.extension() != ".jpg" && file.extension() != ".jpeg")
{
@@ -144,6 +165,7 @@ extern "C"
void* mlx_bmp_file_to_image(void* mlx, char* filename, int* width, int* height)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
std::filesystem::path file(filename);
if(file.extension() != ".bmp" && file.extension() != ".dib")
{
@@ -155,6 +177,7 @@ extern "C"
int mlx_pixel_put(void* mlx, void* win, int x, int y, int color)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
unsigned char color_bits[4];
color_bits[0] = (color & 0x00FF0000) >> 16;
color_bits[1] = (color & 0x0000FF00) >> 8;
@@ -166,6 +189,7 @@ extern "C"
int mlx_string_put(void* mlx, void* win, int x, int y, int color, char* str)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
unsigned char color_bits[4];
color_bits[0] = (color & 0x00FF0000) >> 16;
color_bits[1] = (color & 0x0000FF00) >> 8;
@@ -177,6 +201,7 @@ extern "C"
void mlx_set_font(void* mlx, void* win, char* filepath)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
std::filesystem::path file(filepath);
if(std::strcmp(filepath, "default") != 0 && file.extension() != ".ttf" && file.extension() != ".tte")
{
@@ -188,6 +213,7 @@ extern "C"
void mlx_set_font_scale(void* mlx, void* win, char* filepath, float scale)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
std::filesystem::path file(filepath);
if(std::strcmp(filepath, "default") != 0 && file.extension() != ".ttf" && file.extension() != ".tte")
{
@@ -199,25 +225,30 @@ extern "C"
int mlx_clear_window(void* mlx, void* win)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
static_cast<mlx::core::Application*>(mlx)->clearGraphicsSupport(win);
return 0;
}
int mlx_destroy_window(void* mlx, void* win)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
static_cast<mlx::core::Application*>(mlx)->destroyGraphicsSupport(win);
return 0;
}
int mlx_destroy_display(void* mlx)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
delete static_cast<mlx::core::Application*>(mlx);
mlx::Render_Core::get().destroy();
__mlx_ptr = nullptr;
return 0;
}
int mlx_get_screens_size(void* mlx, int* w, int* h)
{
MLX_CHECK_APPLICATION_POINTER(mlx);
static_cast<mlx::core::Application*>(mlx)->getScreenSize(w, h);
return 0;
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 18:55:57 by maldavid #+# #+# */
/* Updated: 2023/12/12 22:11:47 by kbz_8 ### ########.fr */
/* Updated: 2023/12/16 17:10:17 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -97,22 +97,15 @@ namespace mlx
}
// TODO, use global cmd buffer pool to manage resources
CmdPool cmdpool;
cmdpool.init();
CmdBuffer cmdBuffer;
cmdBuffer.init(&cmdpool);
cmdBuffer.beginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
CmdBuffer& cmd = Render_Core::get().getSingleTimeCmdBuffer();
cmd.beginRecord();
VkBufferCopy copyRegion{};
copyRegion.size = _size;
vkCmdCopyBuffer(cmdBuffer.get(), buffer._buffer, _buffer, 1, &copyRegion);
vkCmdCopyBuffer(cmd.get(), buffer._buffer, _buffer, 1, &copyRegion);
cmdBuffer.endRecord();
cmdBuffer.submitIdle();
cmdBuffer.destroy();
cmdpool.destroy();
cmd.endRecord();
cmd.submitIdle();
return true;
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/12/15 19:57:49 by maldavid #+# #+# */
/* Updated: 2023/12/15 20:21:54 by maldavid ### ########.fr */
/* Updated: 2023/12/16 18:46:26 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -22,7 +22,24 @@ namespace mlx
{
_pool.init();
for(int i = 0; i < MIN_POOL_SIZE; i++)
_buffers.emplace_back().init(&_pool);
{
_buffers.emplace_back();
_buffers.back().init(&_pool);
}
}
CmdBuffer& SingleTimeCmdManager::getCmdBuffer() noexcept
{
for(CmdBuffer& buf : _buffers)
{
if(buf.isReadyToBeUsed())
{
buf.reset();
return buf;
}
}
_buffers.emplace_back().init(&_pool);
return _buffers.back();
}
void SingleTimeCmdManager::destroy() noexcept
@@ -33,15 +50,4 @@ namespace mlx
});
_pool.destroy();
}
CmdBuffer& SingleTimeCmdManager::getCmdBuffer() noexcept
{
for(CmdBuffer& buf : _buffers)
{
if(buf.isReadyToBeUsed())
return buf;
}
_buffers.emplace_back().init(&_pool);
return _buffers.back();
}
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/12/15 18:25:57 by maldavid #+# #+# */
/* Updated: 2023/12/15 19:59:40 by maldavid ### ########.fr */
/* Updated: 2023/12/16 18:09:56 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -35,6 +35,8 @@ namespace mlx
inline static constexpr const uint8_t MIN_POOL_SIZE = 8;
private:
private:
std::vector<CmdBuffer> _buffers;
CmdPool _pool;

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:26:06 by maldavid #+# #+# */
/* Updated: 2023/11/08 20:17:49 by maldavid ### ########.fr */
/* Updated: 2023/12/16 18:51:03 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -39,11 +39,14 @@ namespace mlx
#endif
_fence.init();
_state = state::idle;
}
void CmdBuffer::beginRecord(VkCommandBufferUsageFlags usage)
{
if(_is_recording)
if(!isInit())
core::error::report(e_kind::fatal_error, "Vulkan : begenning record on un uninit command buffer");
if(_state == state::recording)
return;
VkCommandBufferBeginInfo beginInfo{};
@@ -52,17 +55,19 @@ namespace mlx
if(vkBeginCommandBuffer(_cmd_buffer, &beginInfo) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to begin recording command buffer");
_is_recording = true;
_state = state::recording;
}
void CmdBuffer::endRecord()
{
if(!_is_recording)
if(!isInit())
core::error::report(e_kind::fatal_error, "Vulkan : ending record on un uninit command buffer");
if(_state != state::recording)
return;
if(vkEndCommandBuffer(_cmd_buffer) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to end recording command buffer");
_is_recording = false;
_state = state::idle;
}
void CmdBuffer::submitIdle() noexcept
@@ -83,6 +88,8 @@ namespace mlx
vkQueueSubmit(Render_Core::get().getQueue().getGraphic(), 1, &submitInfo, fence);
vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX);
vkDestroyFence(device, fence, nullptr);
_state = state::submitted;
_state = state::ready;
}
void CmdBuffer::submit(Semaphore& semaphores) noexcept
@@ -103,11 +110,13 @@ namespace mlx
if(vkQueueSubmit(Render_Core::get().getQueue().getGraphic(), 1, &submitInfo, _fence.get()) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan error : failed to submit draw command buffer");
_state = state::submitted;
}
void CmdBuffer::destroy() noexcept
{
_fence.destroy();
_cmd_buffer = VK_NULL_HANDLE;
_state = state::uninit;
}
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:25:42 by maldavid #+# #+# */
/* Updated: 2023/12/15 20:19:42 by maldavid ### ########.fr */
/* Updated: 2023/12/16 18:44:48 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -21,6 +21,16 @@ namespace mlx
{
class CmdBuffer
{
public:
enum class state
{
uninit = 0, // buffer not initialized or destroyed
ready, // buffer ready to be used after having been submitted
idle, // buffer has recorded informations but has not been submitted
recording, // buffer is currently recording
submitted, // buffer has been submitted
};
public:
void init(class CmdManager* manager);
void init(class CmdPool* pool);
@@ -29,13 +39,15 @@ namespace mlx
void beginRecord(VkCommandBufferUsageFlags usage = 0);
void submit(class Semaphore& semaphores) noexcept;
void submitIdle() noexcept;
inline void waitForExecution() noexcept { _fence.waitAndReset(); }
inline void waitForExecution() noexcept { _fence.waitAndReset(); _state = state::ready; }
inline void reset() noexcept { vkResetCommandBuffer(_cmd_buffer, 0); }
inline bool isReadyToBeUsed() const noexcept { return _fence.isReady(); }
void endRecord();
inline bool isRecording() const noexcept { return _is_recording; }
inline bool isInit() const noexcept { return _cmd_buffer != VK_NULL_HANDLE; }
inline bool isInit() const noexcept { return _state != state::uninit; }
inline bool isReadyToBeUsed() const noexcept { return _state == state::ready; }
inline bool isRecording() const noexcept { return _state == state::recording; }
inline bool hasBeenSubmitted() const noexcept { return _state == state::submitted; }
inline state getCurrentState() const noexcept { return _state; }
inline VkCommandBuffer& operator()() noexcept { return _cmd_buffer; }
inline VkCommandBuffer& get() noexcept { return _cmd_buffer; }
@@ -45,7 +57,7 @@ namespace mlx
Fence _fence;
VkCommandBuffer _cmd_buffer = VK_NULL_HANDLE;
class CmdPool* _pool = nullptr;
bool _is_recording = false;
state _state = state::uninit;
};
}

View File

@@ -6,7 +6,7 @@
/* By: kbz_8 <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/10/20 22:02:37 by kbz_8 #+# #+# */
/* Updated: 2023/12/10 22:44:55 by kbz_8 ### ########.fr */
/* Updated: 2023/12/16 19:14:15 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -17,7 +17,11 @@
#define VMA_STATIC_VULKAN_FUNCTIONS 0
#define VMA_DYNAMIC_VULKAN_FUNCTIONS 0
#define VMA_VULKAN_VERSION 1002000
#define VMA_ASSERT(expr) (static_cast<bool>(expr) ? void(0) : mlx::core::error::report(e_kind::fatal_error, "Graphics allocator : an assertion has been catched : '%s'", #expr))
#ifdef DEBUG
#define VMA_ASSERT(expr) (static_cast<bool>(expr) ? void(0) : mlx::core::error::report(e_kind::fatal_error, "Graphics allocator : an assertion has been catched : '%s'", #expr))
#else
#define VMA_ASSERT(expr) ((void)0)
#endif
#define VMA_IMPLEMENTATION
#ifdef MLX_COMPILER_CLANG
@@ -93,6 +97,7 @@ namespace mlx
#ifdef DEBUG
core::error::report(e_kind::message, "Graphics Allocator : created new buffer");
#endif
_active_buffers_allocations++;
return allocation;
}
@@ -103,6 +108,7 @@ namespace mlx
#ifdef DEBUG
core::error::report(e_kind::message, "Graphics Allocator : destroyed buffer");
#endif
_active_buffers_allocations--;
}
VmaAllocation GPUallocator::createImage(const VkImageCreateInfo* iminfo, const VmaAllocationCreateInfo* vinfo, VkImage& image, const char* name) noexcept
@@ -115,6 +121,7 @@ namespace mlx
#ifdef DEBUG
core::error::report(e_kind::message, "Graphics Allocator : created new image");
#endif
_active_images_allocations++;
return allocation;
}
@@ -125,6 +132,7 @@ namespace mlx
#ifdef DEBUG
core::error::report(e_kind::message, "Graphics Allocator : destroyed image");
#endif
_active_images_allocations--;
}
void GPUallocator::mapMemory(VmaAllocation allocation, void** data) noexcept
@@ -164,6 +172,10 @@ namespace mlx
void GPUallocator::destroy() noexcept
{
if(_active_images_allocations != 0)
core::error::report(e_kind::error, "Graphics allocator : some user-dependant allocations were not freed before destroying the display (%d active allocations)", _active_images_allocations);
else if(_active_buffers_allocations != 0)
core::error::report(e_kind::error, "Graphics allocator : some MLX-dependant allocations were not freed before destroying the display (%d active allocations), please report, this should not happen", _active_buffers_allocations);
vmaDestroyAllocator(_allocator);
}
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/10/20 02:13:03 by maldavid #+# #+# */
/* Updated: 2023/12/08 19:07:34 by kbz_8 ### ########.fr */
/* Updated: 2023/12/16 18:53:51 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -44,6 +44,8 @@ namespace mlx
private:
VmaAllocator _allocator;
uint32_t _active_buffers_allocations = 0;
uint32_t _active_images_allocations = 0;
};
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/02 17:53:06 by maldavid #+# #+# */
/* Updated: 2023/12/15 20:31:29 by maldavid ### ########.fr */
/* Updated: 2023/12/16 18:47:36 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -23,7 +23,7 @@ namespace mlx
VkResult res;
if((res = vkCreateFence(Render_Core::get().getDevice().get(), &fenceInfo, nullptr, &_fence)) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create CPU synchronization object, %s", RCore::verbaliseResultVk(res));
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a synchronization object (fence), %s", RCore::verbaliseResultVk(res));
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : created new fence");
#endif

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/02 17:52:09 by maldavid #+# #+# */
/* Updated: 2023/12/15 20:31:25 by maldavid ### ########.fr */
/* Updated: 2023/12/16 17:27:28 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 19:01:08 by maldavid #+# #+# */
/* Updated: 2023/12/12 15:51:37 by kbz_8 ### ########.fr */
/* Updated: 2023/12/16 18:47:29 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -24,7 +24,7 @@ namespace mlx
VkResult res;
if( (res = vkCreateSemaphore(Render_Core::get().getDevice().get(), &semaphoreInfo, nullptr, &_imageAvailableSemaphores)) != VK_SUCCESS ||
(res = vkCreateSemaphore(Render_Core::get().getDevice().get(), &semaphoreInfo, nullptr, &_renderFinishedSemaphores)) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create GPU synchronization object, %s", RCore::verbaliseResultVk(res));
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a synchronization object (semaphore), %s", RCore::verbaliseResultVk(res));
#ifdef DEBUG
core::error::report(e_kind::message, "Vulkan : created new semaphore");
#endif

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/01/25 11:59:07 by maldavid #+# #+# */
/* Updated: 2023/11/18 17:21:14 by maldavid ### ########.fr */
/* Updated: 2023/12/16 17:10:33 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -167,8 +167,6 @@ namespace mlx
}
_allocation = Render_Core::get().getAllocator().createImage(&imageInfo, &alloc_info, _image, name);
_pool.init();
}
void Image::createImageView(VkImageViewType type, VkImageAspectFlags aspectFlags) noexcept
@@ -209,11 +207,8 @@ namespace mlx
void Image::copyFromBuffer(Buffer& buffer)
{
if(!_transfer_cmd.isInit())
_transfer_cmd.init(&_pool);
_transfer_cmd.reset();
_transfer_cmd.beginRecord();
CmdBuffer& cmd = Render_Core::get().getSingleTimeCmdBuffer();
cmd.beginRecord();
VkImageMemoryBarrier copy_barrier{};
copy_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
@@ -226,7 +221,7 @@ namespace mlx
copy_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copy_barrier.subresourceRange.levelCount = 1;
copy_barrier.subresourceRange.layerCount = 1;
vkCmdPipelineBarrier(_transfer_cmd.get(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &copy_barrier);
vkCmdPipelineBarrier(cmd.get(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &copy_barrier);
VkBufferImageCopy region{};
region.bufferOffset = 0;
@@ -239,7 +234,7 @@ namespace mlx
region.imageOffset = { 0, 0, 0 };
region.imageExtent = { _width, _height, 1 };
vkCmdCopyBufferToImage(_transfer_cmd.get(), buffer.get(), _image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
vkCmdCopyBufferToImage(cmd.get(), buffer.get(), _image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
VkImageMemoryBarrier use_barrier{};
use_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
@@ -253,19 +248,16 @@ namespace mlx
use_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
use_barrier.subresourceRange.levelCount = 1;
use_barrier.subresourceRange.layerCount = 1;
vkCmdPipelineBarrier(_transfer_cmd.get(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &use_barrier);
vkCmdPipelineBarrier(cmd.get(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &use_barrier);
_transfer_cmd.endRecord();
_transfer_cmd.submitIdle();
cmd.endRecord();
cmd.submitIdle();
}
void Image::copyToBuffer(Buffer& buffer)
{
if(!_transfer_cmd.isInit())
_transfer_cmd.init(&_pool);
_transfer_cmd.reset();
_transfer_cmd.beginRecord();
CmdBuffer& cmd = Render_Core::get().getSingleTimeCmdBuffer();
cmd.beginRecord();
VkImageMemoryBarrier copy_barrier{};
copy_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
@@ -278,7 +270,7 @@ namespace mlx
copy_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copy_barrier.subresourceRange.levelCount = 1;
copy_barrier.subresourceRange.layerCount = 1;
vkCmdPipelineBarrier(_transfer_cmd.get(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &copy_barrier);
vkCmdPipelineBarrier(cmd.get(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &copy_barrier);
VkBufferImageCopy region{};
region.bufferOffset = 0;
@@ -291,7 +283,7 @@ namespace mlx
region.imageOffset = { 0, 0, 0 };
region.imageExtent = { _width, _height, 1 };
vkCmdCopyImageToBuffer(_transfer_cmd.get(), _image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer.get(), 1, &region);
vkCmdCopyImageToBuffer(cmd.get(), _image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer.get(), 1, &region);
VkImageMemoryBarrier use_barrier{};
use_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
@@ -305,10 +297,10 @@ namespace mlx
use_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
use_barrier.subresourceRange.levelCount = 1;
use_barrier.subresourceRange.layerCount = 1;
vkCmdPipelineBarrier(_transfer_cmd.get(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &use_barrier);
vkCmdPipelineBarrier(cmd.get(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &use_barrier);
_transfer_cmd.endRecord();
_transfer_cmd.submitIdle();
cmd.endRecord();
cmd.submitIdle();
}
void Image::transitionLayout(VkImageLayout new_layout)
@@ -316,10 +308,8 @@ namespace mlx
if(new_layout == _layout)
return;
if(!_transfer_cmd.isInit())
_transfer_cmd.init(&_pool);
_transfer_cmd.reset();
_transfer_cmd.beginRecord();
CmdBuffer& cmd = Render_Core::get().getSingleTimeCmdBuffer();
cmd.beginRecord();
VkImageMemoryBarrier barrier{};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
@@ -354,10 +344,10 @@ namespace mlx
else
destinationStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
vkCmdPipelineBarrier(_transfer_cmd.get(), sourceStage, destinationStage, 0, 0, nullptr, 0, nullptr, 1, &barrier);
vkCmdPipelineBarrier(cmd.get(), sourceStage, destinationStage, 0, 0, nullptr, 0, nullptr, 1, &barrier);
_transfer_cmd.endRecord();
_transfer_cmd.submitIdle();
cmd.endRecord();
cmd.submitIdle();
_layout = new_layout;
}
@@ -379,7 +369,6 @@ namespace mlx
{
destroySampler();
destroyImageView();
destroyCmdPool();
if(_image != VK_NULL_HANDLE)
Render_Core::get().getAllocator().destroyImage(_allocation, _image);

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/01/25 11:54:21 by maldavid #+# #+# */
/* Updated: 2023/12/15 21:07:34 by maldavid ### ########.fr */
/* Updated: 2023/12/15 21:44:30 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -39,7 +39,6 @@ namespace mlx
_width = width;
_height = height;
_layout = layout;
_pool.init();
}
void create(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, const char* name, bool decated_memory = false);
void createImageView(VkImageViewType type, VkImageAspectFlags aspectFlags) noexcept;
@@ -64,11 +63,8 @@ namespace mlx
private:
void destroySampler() noexcept;
void destroyImageView() noexcept;
inline void destroyCmdPool() noexcept { _transfer_cmd.destroy(); _pool.destroy(); }
private:
CmdBuffer _transfer_cmd;
CmdPool _pool;
VmaAllocation _allocation;
VkImage _image = VK_NULL_HANDLE;
VkImageView _image_view = VK_NULL_HANDLE;

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:22:28 by maldavid #+# #+# */
/* Updated: 2023/12/10 22:32:54 by kbz_8 ### ########.fr */
/* Updated: 2023/12/15 21:49:19 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -146,9 +146,6 @@ namespace mlx
vkDestroySwapchainKHR(Render_Core::get().getDevice().get(), _swapChain, nullptr);
_swapChain = VK_NULL_HANDLE;
for(Image& img : _images)
{
img.destroyImageView();
img.destroyCmdPool();
}
}
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/04 17:55:21 by maldavid #+# #+# */
/* Updated: 2023/12/15 21:08:07 by maldavid ### ########.fr */
/* Updated: 2023/12/16 19:14:56 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */