From d56b224d429fbb7136537663aa4bb5b33eacc239 Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Wed, 13 Dec 2023 00:33:34 +0100 Subject: [PATCH 1/6] working on font system --- 4 | 83 +++++++++++++++++++++++++++++ src/renderer/buffers/vk_buffer.cpp | 63 ++++++++++++++-------- src/renderer/buffers/vk_buffer.h | 5 +- src/renderer/buffers/vk_vbo.cpp | 26 ++++++++- src/renderer/buffers/vk_vbo.h | 12 ++++- src/renderer/font.cpp | 84 ++++++++++++++++++++++++++++++ src/renderer/font.h | 53 +++++++++++++++++++ src/renderer/text_library.cpp | 21 +++++--- src/renderer/text_library.h | 11 ++-- src/renderer/text_pipeline.cpp | 58 +++------------------ src/renderer/text_pipeline.h | 9 ++-- 11 files changed, 333 insertions(+), 92 deletions(-) create mode 100644 4 create mode 100644 src/renderer/font.cpp create mode 100644 src/renderer/font.h diff --git a/4 b/4 new file mode 100644 index 0000000..042353f --- /dev/null +++ b/4 @@ -0,0 +1,83 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* text_library.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maldavid +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/04/10 11:59:57 by maldavid #+# #+# */ +/* Updated: 2023/12/12 22:47:33 by kbz_8 ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include +#include + +namespace mlx +{ + void TextData::init(std::string text, Font const* font, std::vector vbo_data, std::vector ibo_data) + { + _text = std::move(text); + _font = font; + #ifdef DEBUG + for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) + _vbo[i].create(sizeof(Vertex) * vbo_data.size(), static_cast(vbo_data.data()), _text.c_str()); + _ibo.create(sizeof(uint16_t) * ibo_data.size(), ibo_data.data(), _text.c_str()); + #else + for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) + _vbo[i].create(sizeof(Vertex) * vbo_data.size(), static_cast(vbo_data.data()), nullptr); + _ibo.create(sizeof(uint16_t) * ibo_data.size(), ibo_data.data(), nullptr); + #endif + } + + void TextData::bind(Renderer& renderer) noexcept + { + _vbo[renderer.getActiveImageIndex()].bind(renderer); + _ibo.bind(renderer); + } + + void TextData::destroy() noexcept + { + for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) + _vbo[i].destroy(); + _ibo.destroy(); + } + + std::shared_ptr TextLibrary::getTextData(TextID id) + { + if(!_cache.count(id)) + core::error::report(e_kind::fatal_error, "Text Library : wrong text ID '%d'", id); + return _cache[id]; + } + + TextID TextLibrary::addTextToLibrary(std::shared_ptr text) + { + auto it = std::find_if(_cache.begin(), _cache.end(), [=](const std::pair>& v) + { + return v.second->getText() == text->getText(); + }); + if(it != _cache.end()) + return it->first; + _cache[_current_id] = text; + _current_id++; + return _current_id - 1; + } + + void TextLibrary::removeTextFromLibrary(TextID id) + { + if(_cache.count(id)) + { + _cache[id]->destroy(); + _cache.erase(id); + } + } + + void TextLibrary::clearLibrary() + { + for(auto [id, text] : _cache) + text->destroy(); + _cache.clear(); + } +} diff --git a/src/renderer/buffers/vk_buffer.cpp b/src/renderer/buffers/vk_buffer.cpp index bd25952..a98bb74 100644 --- a/src/renderer/buffers/vk_buffer.cpp +++ b/src/renderer/buffers/vk_buffer.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/08 18:55:57 by maldavid #+# #+# */ -/* Updated: 2023/12/10 23:05:14 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/12 22:11:47 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -23,9 +23,9 @@ namespace mlx void Buffer::create(Buffer::kind type, VkDeviceSize size, VkBufferUsageFlags usage, const char* name, const void* data) { _usage = usage; - if(type == Buffer::kind::constant) + if(type == Buffer::kind::constant || type == Buffer::kind::dynamic_device_local) { - if(data == nullptr) + if(data == nullptr && type == Buffer::kind::constant) { core::error::report(e_kind::warning, "Vulkan : trying to create constant buffer without data (constant buffers cannot be modified after creation)"); return; @@ -45,7 +45,7 @@ namespace mlx mapMem(&mapped); std::memcpy(mapped, data, size); unmapMem(); - if(type == Buffer::kind::constant) + if(type == Buffer::kind::constant || type == Buffer::kind::dynamic_device_local) pushToGPU(); } } @@ -83,6 +83,40 @@ namespace mlx _size = size; } + bool Buffer::copyFromBuffer(const Buffer& buffer) noexcept + { + if(!(_usage & VK_BUFFER_USAGE_TRANSFER_DST_BIT)) + { + core::error::report(e_kind::error, "Vulkan : buffer cannot be the destination of a copy because it does not have the correct usage flag"); + return false; + } + if(!(buffer._usage & VK_BUFFER_USAGE_TRANSFER_SRC_BIT)) + { + core::error::report(e_kind::error, "Vulkan : buffer cannot be the source of a copy because it does not have the correct usage flag"); + return false; + } + + // 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); + + VkBufferCopy copyRegion{}; + copyRegion.size = _size; + vkCmdCopyBuffer(cmdBuffer.get(), buffer._buffer, _buffer, 1, ©Region); + + cmdBuffer.endRecord(); + cmdBuffer.submitIdle(); + + cmdBuffer.destroy(); + cmdpool.destroy(); + + return true; + } + void Buffer::pushToGPU() noexcept { VmaAllocationCreateInfo alloc_info{}; @@ -97,25 +131,8 @@ namespace mlx newBuffer.createBuffer(newBuffer._usage, alloc_info, _size, nullptr); #endif - CmdPool cmdpool; - cmdpool.init(); - CmdBuffer cmdBuffer; - cmdBuffer.init(&cmdpool); - - cmdBuffer.beginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); - - VkBufferCopy copyRegion{}; - copyRegion.size = _size; - vkCmdCopyBuffer(cmdBuffer.get(), _buffer, newBuffer._buffer, 1, ©Region); - - cmdBuffer.endRecord(); - cmdBuffer.submitIdle(); - - cmdBuffer.destroy(); - cmdpool.destroy(); - - this->swap(newBuffer); - + if(newBuffer.copyFromBuffer(*this)) // if the copy succeded we swap the buffers, else the new one is deleted + this->swap(newBuffer); newBuffer.destroy(); } diff --git a/src/renderer/buffers/vk_buffer.h b/src/renderer/buffers/vk_buffer.h index 08b4344..f3f1669 100644 --- a/src/renderer/buffers/vk_buffer.h +++ b/src/renderer/buffers/vk_buffer.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/06 23:18:52 by maldavid #+# #+# */ -/* Updated: 2023/12/11 19:47:39 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/12 21:12:44 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,7 +22,7 @@ namespace mlx class Buffer { public: - enum class kind { dynamic, uniform, constant }; + enum class kind { dynamic, dynamic_device_local, uniform, constant }; void create(kind type, VkDeviceSize size, VkBufferUsageFlags usage, const char* name, const void* data = nullptr); void destroy() noexcept; @@ -32,6 +32,7 @@ namespace mlx inline void unmapMem() noexcept { Render_Core::get().getAllocator().unmapMemory(_allocation); _is_mapped = false; } void flush(VkDeviceSize size = VK_WHOLE_SIZE, VkDeviceSize offset = 0); + bool copyFromBuffer(const Buffer& buffer) noexcept; inline VkBuffer& operator()() noexcept { return _buffer; } inline VkBuffer& get() noexcept { return _buffer; } diff --git a/src/renderer/buffers/vk_vbo.cpp b/src/renderer/buffers/vk_vbo.cpp index 1b2a0d3..8ceab7d 100644 --- a/src/renderer/buffers/vk_vbo.cpp +++ b/src/renderer/buffers/vk_vbo.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/06 18:28:08 by maldavid #+# #+# */ -/* Updated: 2023/11/10 08:33:52 by maldavid ### ########.fr */ +/* Updated: 2023/12/12 22:17:14 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,7 +18,10 @@ namespace mlx void VBO::setData(uint32_t size, const void* data) { if(size > getSize()) + { core::error::report(e_kind::error, "Vulkan : trying to store to much data in a vertex buffer (%d bytes in %d bytes)", size, getSize()); + return; + } if(data == nullptr) core::error::report(e_kind::warning, "Vulkan : mapping null data in a vertex buffer"); @@ -28,4 +31,25 @@ namespace mlx std::memcpy(temp, data, static_cast(size)); unmapMem(); } + + void D_VBO::setData(uint32_t size, const void* data) + { + if(size > getSize()) + { + core::error::report(e_kind::error, "Vulkan : trying to store to much data in a vertex buffer (%d bytes in %d bytes)", size, getSize()); + return; + } + + if(data == nullptr) + core::error::report(e_kind::warning, "Vulkan : mapping null data in a vertex buffer"); + + Buffer tmp_buf; + #ifdef DEBUG + tmp_buf.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, "tmp_buffer", data); + #else + tmp_buf.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, nullptr, data); + #endif + copyFromBuffer(tmp_buf); + tmp_buf.destroy(); + } } diff --git a/src/renderer/buffers/vk_vbo.h b/src/renderer/buffers/vk_vbo.h index 6c67332..1bf2209 100644 --- a/src/renderer/buffers/vk_vbo.h +++ b/src/renderer/buffers/vk_vbo.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/06 18:27:38 by maldavid #+# #+# */ -/* Updated: 2023/12/08 19:06:45 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/12 22:46:21 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,7 +22,15 @@ namespace mlx class VBO : public Buffer { public: - inline void create(uint32_t size, const char* name) { Buffer::create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, name); } + 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); } + void setData(uint32_t size, const void* data); + inline void bind(Renderer& renderer) noexcept { vkCmdBindVertexBuffers(renderer.getActiveCmdBuffer().get(), 0, 1, &_buffer, &_offset); } + }; + + class D_VBO : public Buffer + { + public: + 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); } void setData(uint32_t size, const void* data); inline void bind(Renderer& renderer) noexcept { vkCmdBindVertexBuffers(renderer.getActiveCmdBuffer().get(), 0, 1, &_buffer, &_offset); } }; diff --git a/src/renderer/font.cpp b/src/renderer/font.cpp new file mode 100644 index 0000000..a75aadb --- /dev/null +++ b/src/renderer/font.cpp @@ -0,0 +1,84 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* font.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maldavid +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/11 22:06:09 by kbz_8 #+# #+# */ +/* Updated: 2023/12/12 23:57:53 by kbz_8 ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include + +constexpr const int RANGE = 1024; + +namespace mlx +{ + Font::Font(Renderer& renderer, const std::filesystem::path& path, float scale) : non_copyable(), _name(path.string()) + { + std::vector tmp_bitmap(RANGE * RANGE); + std::vector vulkan_bitmap(RANGE * RANGE * 4); + + std::ifstream file(path, std::ios::binary); + if(!file.is_open()) + { + core::error::report(e_kind::error, "Font load : cannot open font file, %s", _name.c_str()); + return; + } + std::ifstream::pos_type fileSize = std::filesystem::file_size(path); + file.seekg(0, std::ios::beg); + std::vector bytes(fileSize); + file.read(reinterpret_cast(bytes.data()), fileSize); + file.close(); + + stbtt_pack_context pc; + stbtt_PackBegin(&pc, tmp_bitmap.data(), RANGE, RANGE, RANGE, 1, nullptr); + stbtt_PackFontRange(&pc, bytes.data(), 0, scale, 32, 96, _cdata.data()); + stbtt_PackEnd(&pc); + for(int i = 0, j = 0; i < RANGE * RANGE; i++, j += 4) + { + vulkan_bitmap[j + 0] = tmp_bitmap[i]; + vulkan_bitmap[j + 1] = tmp_bitmap[i]; + vulkan_bitmap[j + 2] = tmp_bitmap[i]; + vulkan_bitmap[j + 3] = tmp_bitmap[i]; + } + #ifdef DEBUG + _atlas.create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, std::string(name + "_font_altas").c_str(), true); + #else + _atlas.create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, nullptr, true); + #endif + _atlas.setDescriptor(renderer.getFragDescriptorSet().duplicate()); + } + + Font::Font(class Renderer& renderer, const std::string& name, const std::vector& ttf_data, float scale) + { + std::vector tmp_bitmap(RANGE * RANGE); + std::vector vulkan_bitmap(RANGE * RANGE * 4); + stbtt_pack_context pc; + stbtt_PackBegin(&pc, tmp_bitmap.data(), RANGE, RANGE, RANGE, 1, nullptr); + stbtt_PackFontRange(&pc, ttf_data.data(), 0, 6.0, 32, 96, _cdata.data()); + stbtt_PackEnd(&pc); + for(int i = 0, j = 0; i < RANGE * RANGE; i++, j += 4) + { + vulkan_bitmap[j + 0] = tmp_bitmap[i]; + vulkan_bitmap[j + 1] = tmp_bitmap[i]; + vulkan_bitmap[j + 2] = tmp_bitmap[i]; + vulkan_bitmap[j + 3] = tmp_bitmap[i]; + } + #ifdef DEBUG + _atlas.create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, std::string(name + "_font_altas").c_str(), true); + #else + _atlas.create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, nullptr, true); + #endif + _atlas.setDescriptor(renderer.getFragDescriptorSet().duplicate()); + } + + Font::~Font() + { + _atlas.destroy(); + } +} diff --git a/src/renderer/font.h b/src/renderer/font.h new file mode 100644 index 0000000..8e3ba08 --- /dev/null +++ b/src/renderer/font.h @@ -0,0 +1,53 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* font.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maldavid +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/11 21:17:04 by kbz_8 #+# #+# */ +/* Updated: 2023/12/13 00:25:30 by kbz_8 ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef __MLX_FONT__ +#define __MLX_FONT__ + +#include +#include +#include +#include + +namespace mlx +{ + class Font : public non_copyable + { + public: + Font(class Renderer& renderer, const std::filesystem::path& path, float scale); + Font(class Renderer& renderer, const std::string& name, const std::vector& ttf_data, float scale); + inline const std::string& getName() const { return _name; } + inline const std::array& getCharData() const { return _cdata; } + inline VkDescriptorSet getDescriptorSet() noexcept { return _atlas.getSet(); } + inline bool operator==(const Font& rhs) { return rhs._name == _name; } + ~Font(); + + private: + std::array _cdata; + TextureAtlas _atlas; + std::string _name; + }; +} + +namespace std +{ + template <> + struct hash + { + std::size_t operator()(const mlx::Font& f) const noexcept + { + return std::hash()(f.getName()); + } + }; +} + +#endif diff --git a/src/renderer/text_library.cpp b/src/renderer/text_library.cpp index ec34951..0a68dd4 100644 --- a/src/renderer/text_library.cpp +++ b/src/renderer/text_library.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/10 11:59:57 by maldavid #+# #+# */ -/* Updated: 2023/11/16 13:45:31 by maldavid ### ########.fr */ +/* Updated: 2023/12/12 23:03:33 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,27 +17,36 @@ namespace mlx { - void TextData::init(std::string text, std::vector vbo_data, std::vector ibo_data) + void TextData::init(std::string text, Font const* font, std::vector vbo_data, std::vector ibo_data) { _text = std::move(text); + _font = font; #ifdef DEBUG - _vbo.create(sizeof(Vertex) * vbo_data.size(), vbo_data.data(), _text.c_str()); + for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) + _vbo[i].create(sizeof(Vertex) * vbo_data.size(), static_cast(vbo_data.data()), _text.c_str()); _ibo.create(sizeof(uint16_t) * ibo_data.size(), ibo_data.data(), _text.c_str()); #else - _vbo.create(sizeof(Vertex) * vbo_data.size(), vbo_data.data(), nullptr); + for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) + _vbo[i].create(sizeof(Vertex) * vbo_data.size(), static_cast(vbo_data.data()), nullptr); _ibo.create(sizeof(uint16_t) * ibo_data.size(), ibo_data.data(), nullptr); #endif } void TextData::bind(Renderer& renderer) noexcept { - _vbo.bind(renderer); + _vbo[renderer.getActiveImageIndex()].bind(renderer); _ibo.bind(renderer); } + void TextData::updateVertexData(int frame, std::vector vbo_data) + { + _vbo[frame].setData(sizeof(Vertex) * vbo_data.size(), static_cast(vbo_data.data())); + } + void TextData::destroy() noexcept { - _vbo.destroy(); + for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) + _vbo[i].destroy(); _ibo.destroy(); } diff --git a/src/renderer/text_library.h b/src/renderer/text_library.h index b889224..1283a99 100644 --- a/src/renderer/text_library.h +++ b/src/renderer/text_library.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/10 11:52:30 by maldavid #+# #+# */ -/* Updated: 2023/12/08 19:12:24 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/12 23:07:13 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,6 +21,8 @@ #include #include #include +#include +#include namespace mlx { @@ -32,8 +34,10 @@ namespace mlx public: TextData() = default; - void init(std::string text, std::vector vbo_data, std::vector ibo_data); + void init(std::string text, Font const* font, std::vector vbo_data, std::vector ibo_data); void bind(class Renderer& renderer) noexcept; + inline const Font& getFontInUse() const noexcept { return *_font; } + void updateVertexData(int frame, std::vector vbo_data); inline uint32_t getIBOsize() noexcept { return _ibo.getSize(); } inline const std::string& getText() const { return _text; } void destroy() noexcept; @@ -41,9 +45,10 @@ namespace mlx ~TextData() = default; private: - C_VBO _vbo; + std::array _vbo; C_IBO _ibo; std::string _text; + Font const* _font = nullptr; }; class TextLibrary diff --git a/src/renderer/text_pipeline.cpp b/src/renderer/text_pipeline.cpp index 4468a0b..d5606d4 100644 --- a/src/renderer/text_pipeline.cpp +++ b/src/renderer/text_pipeline.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/06 16:41:13 by maldavid #+# #+# */ -/* Updated: 2023/12/11 15:12:02 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/13 00:25:48 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -36,7 +36,7 @@ namespace mlx text(std::move(_text)) {} - void TextDrawData::init(TextLibrary& library, std::array& cdata) noexcept + void TextDrawData::init(TextLibrary& library, Font* const font) noexcept { std::vector vertexData; std::vector indexData; @@ -50,7 +50,7 @@ namespace mlx continue; stbtt_aligned_quad q; - stbtt_GetPackedQuad(cdata.data(), RANGE, RANGE, c - 32, &stb_x, &stb_y, &q, 1); + stbtt_GetPackedQuad(font->getCharData().data(), RANGE, RANGE, c - 32, &stb_x, &stb_y, &q, 1); std::size_t index = vertexData.size(); @@ -67,7 +67,7 @@ namespace mlx indexData.emplace_back(index + 0); } std::shared_ptr text_data = std::make_shared(); - text_data->init(text, std::move(vertexData), std::move(indexData)); + text_data->init(text, font, std::move(vertexData), std::move(indexData)); id = library.addTextToLibrary(text_data); #ifdef DEBUG @@ -78,61 +78,19 @@ namespace mlx void TextPutPipeline::init(Renderer* renderer) noexcept { _renderer = renderer; - std::vector tmp_bitmap(RANGE * RANGE); - std::vector vulkan_bitmap(RANGE * RANGE * 4); - stbtt_pack_context pc; - stbtt_PackBegin(&pc, tmp_bitmap.data(), RANGE, RANGE, RANGE, 1, nullptr); - stbtt_PackFontRange(&pc, dogica_ttf, 0, 6.0, 32, 96, _cdata.data()); - stbtt_PackEnd(&pc); - for(int i = 0, j = 0; i < RANGE * RANGE; i++, j += 4) - { - vulkan_bitmap[j + 0] = tmp_bitmap[i]; - vulkan_bitmap[j + 1] = tmp_bitmap[i]; - vulkan_bitmap[j + 2] = tmp_bitmap[i]; - vulkan_bitmap[j + 3] = tmp_bitmap[i]; - } - _atlas.create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, "__mlx_texts_pipeline_texture_atlas", true); - _atlas.setDescriptor(renderer->getFragDescriptorSet().duplicate()); + _font_set.emplace(*_renderer, "default", dogica_ttf, 6.0f); } void TextPutPipeline::loadFont(const std::filesystem::path& filepath, float scale) { - std::vector tmp_bitmap(RANGE * RANGE); - std::vector vulkan_bitmap(RANGE * RANGE * 4); - - std::ifstream file(filepath, std::ios::binary); - if(!file.is_open()) - { - core::error::report(e_kind::error, "Font load : cannot open font file, %s", filepath.string().c_str()); - return; - } - std::ifstream::pos_type fileSize = std::filesystem::file_size(filepath); - file.seekg(0, std::ios::beg); - std::vector bytes(fileSize); - file.read(reinterpret_cast(bytes.data()), fileSize); - file.close(); - - stbtt_pack_context pc; - stbtt_PackBegin(&pc, tmp_bitmap.data(), RANGE, RANGE, RANGE, 1, nullptr); - stbtt_PackFontRange(&pc, bytes.data(), 0, scale, 32, 96, _cdata.data()); - stbtt_PackEnd(&pc); - for(int i = 0, j = 0; i < RANGE * RANGE; i++, j += 4) - { - vulkan_bitmap[j + 0] = tmp_bitmap[i]; - vulkan_bitmap[j + 1] = tmp_bitmap[i]; - vulkan_bitmap[j + 2] = tmp_bitmap[i]; - vulkan_bitmap[j + 3] = tmp_bitmap[i]; - } - destroy(); - _atlas.create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, "__mlx_texts_pipeline_texture_atlas", true); - _atlas.setDescriptor(_renderer->getFragDescriptorSet().duplicate()); + _font_set.emplace(*_renderer, filepath, scale); } void TextPutPipeline::put(int x, int y, int color, std::string str) { auto res = _drawlist.emplace(std::move(str), color, x, y); if(res.second) - const_cast(*res.first).init(_library, _cdata); + const_cast(*res.first).init(_library, _font_in_use); } void TextPutPipeline::render() @@ -150,6 +108,6 @@ namespace mlx { _library.clearLibrary(); _drawlist.clear(); - _atlas.destroy(); + _font_set.clear(); } } diff --git a/src/renderer/text_pipeline.h b/src/renderer/text_pipeline.h index b6ca962..db6f405 100644 --- a/src/renderer/text_pipeline.h +++ b/src/renderer/text_pipeline.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/06 16:24:11 by maldavid #+# #+# */ -/* Updated: 2023/12/08 19:12:40 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/13 00:24:21 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -33,7 +33,7 @@ namespace mlx std::string text; TextDrawData(std::string text, int _color, int _x, int _y); - void init(TextLibrary& library, std::array& cdata) noexcept; + void init(TextLibrary& library, Font* const font) noexcept; bool operator==(const TextDrawData& rhs) const { return text == rhs.text && x == rhs.x && y == rhs.y && color == rhs.color; } }; } @@ -59,7 +59,6 @@ namespace mlx void init(Renderer* renderer) noexcept; void put(int x, int y, int color, std::string str); - inline VkDescriptorSet getDescriptorSet() noexcept { return _atlas.getSet(); } inline void clear() { _drawlist.clear(); } void loadFont(const std::filesystem::path& filepath, float scale); void render(); @@ -68,11 +67,11 @@ namespace mlx ~TextPutPipeline() = default; private: - std::array _cdata; - TextureAtlas _atlas; + std::unordered_set _font_set; TextLibrary _library; std::unordered_set _drawlist; Renderer* _renderer = nullptr; + Font* _font_in_use = nullptr; }; } From 80396388853798c005b15d2e664d9b51cb29e5de Mon Sep 17 00:00:00 2001 From: kbz_8 Date: Wed, 13 Dec 2023 16:06:43 +0100 Subject: [PATCH 2/6] removed garbage file --- 4 | 83 --------------------------------------------------------------- 1 file changed, 83 deletions(-) delete mode 100644 4 diff --git a/4 b/4 deleted file mode 100644 index 042353f..0000000 --- a/4 +++ /dev/null @@ -1,83 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* text_library.cpp :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: maldavid +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2023/04/10 11:59:57 by maldavid #+# #+# */ -/* Updated: 2023/12/12 22:47:33 by kbz_8 ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include -#include -#include -#include - -namespace mlx -{ - void TextData::init(std::string text, Font const* font, std::vector vbo_data, std::vector ibo_data) - { - _text = std::move(text); - _font = font; - #ifdef DEBUG - for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) - _vbo[i].create(sizeof(Vertex) * vbo_data.size(), static_cast(vbo_data.data()), _text.c_str()); - _ibo.create(sizeof(uint16_t) * ibo_data.size(), ibo_data.data(), _text.c_str()); - #else - for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) - _vbo[i].create(sizeof(Vertex) * vbo_data.size(), static_cast(vbo_data.data()), nullptr); - _ibo.create(sizeof(uint16_t) * ibo_data.size(), ibo_data.data(), nullptr); - #endif - } - - void TextData::bind(Renderer& renderer) noexcept - { - _vbo[renderer.getActiveImageIndex()].bind(renderer); - _ibo.bind(renderer); - } - - void TextData::destroy() noexcept - { - for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) - _vbo[i].destroy(); - _ibo.destroy(); - } - - std::shared_ptr TextLibrary::getTextData(TextID id) - { - if(!_cache.count(id)) - core::error::report(e_kind::fatal_error, "Text Library : wrong text ID '%d'", id); - return _cache[id]; - } - - TextID TextLibrary::addTextToLibrary(std::shared_ptr text) - { - auto it = std::find_if(_cache.begin(), _cache.end(), [=](const std::pair>& v) - { - return v.second->getText() == text->getText(); - }); - if(it != _cache.end()) - return it->first; - _cache[_current_id] = text; - _current_id++; - return _current_id - 1; - } - - void TextLibrary::removeTextFromLibrary(TextID id) - { - if(_cache.count(id)) - { - _cache[id]->destroy(); - _cache.erase(id); - } - } - - void TextLibrary::clearLibrary() - { - for(auto [id, text] : _cache) - text->destroy(); - _cache.clear(); - } -} From c013237219a30e217adae8505f9567646100bbfb Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Thu, 14 Dec 2023 00:08:38 +0100 Subject: [PATCH 3/6] yes --- src/renderer/text_pipeline.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/renderer/text_pipeline.cpp b/src/renderer/text_pipeline.cpp index d5606d4..a6fae69 100644 --- a/src/renderer/text_pipeline.cpp +++ b/src/renderer/text_pipeline.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/06 16:41:13 by maldavid #+# #+# */ -/* Updated: 2023/12/13 00:25:48 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/14 00:06:29 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -78,12 +78,12 @@ namespace mlx void TextPutPipeline::init(Renderer* renderer) noexcept { _renderer = renderer; - _font_set.emplace(*_renderer, "default", dogica_ttf, 6.0f); + _font_in_use = &const_cast(*_font_set.emplace(*_renderer, "default", dogica_ttf, 6.0f).first); } void TextPutPipeline::loadFont(const std::filesystem::path& filepath, float scale) { - _font_set.emplace(*_renderer, filepath, scale); + _font_in_use = &const_cast(*_font_set.emplace(*_renderer, filepath, scale).first); } void TextPutPipeline::put(int x, int y, int color, std::string str) From d08a97f55c2e0d0ec433297dd79c72d351cdd591 Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Thu, 14 Dec 2023 19:13:41 +0100 Subject: [PATCH 4/6] adding multiple font support --- includes/mlx.h | 6 ++-- src/core/bridge.cpp | 6 ++-- src/core/graphics.cpp | 8 ++--- src/core/graphics.inl | 9 +----- .../descriptors/vk_descriptor_set.cpp | 6 ++-- src/renderer/descriptors/vk_descriptor_set.h | 8 ++--- src/renderer/font.cpp | 12 +++---- src/renderer/font.h | 15 ++++++--- src/renderer/images/texture.h | 14 +------- src/renderer/images/texture_atlas.cpp | 4 +-- src/renderer/images/texture_atlas.h | 6 ++-- src/renderer/images/vk_image.h | 10 +++--- src/renderer/pixel_put.cpp | 8 ++--- src/renderer/pixel_put.h | 4 +-- src/renderer/text_pipeline.cpp | 25 ++++++++++++--- src/renderer/text_pipeline.h | 12 ++++--- src/utils/combine_hash.h | 32 +++++++++++++++++++ src/utils/dogica_ttf.h | 6 ++-- test/main.c | 15 ++++----- valgrind.supp | 11 ++++++- 20 files changed, 131 insertions(+), 86 deletions(-) create mode 100644 src/utils/combine_hash.h diff --git a/includes/mlx.h b/includes/mlx.h index bab16ee..5e68ad4 100644 --- a/includes/mlx.h +++ b/includes/mlx.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 16:56:35 by maldavid #+# #+# */ -/* Updated: 2023/12/11 20:35:41 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/14 16:27:44 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -282,7 +282,7 @@ MLX_API int mlx_string_put(void* mlx, void* win, int x, int y, int color, char* * * @param mlx Internal MLX application * @param win Internal window - * @param filepath Filepath to the font + * @param filepath Filepath to the font or "default" to reset to the embedded font * * @return (void) */ @@ -293,7 +293,7 @@ MLX_API void mlx_set_font(void* mlx, void* win, char* filepath); * * @param mlx Internal MLX application * @param win Internal window - * @param filepath Filepath to the font + * @param filepath Filepath to the font or "default" to reset to the embedded font * @param scale Scale to apply to the font * * @return (void) diff --git a/src/core/bridge.cpp b/src/core/bridge.cpp index af8ff8b..4091d3a 100644 --- a/src/core/bridge.cpp +++ b/src/core/bridge.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 17:35:20 by maldavid #+# #+# */ -/* Updated: 2023/12/11 15:56:18 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/14 17:47:17 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -178,7 +178,7 @@ extern "C" void mlx_set_font(void* mlx, void* win, char* filepath) { std::filesystem::path file(filepath); - if(file.extension() != ".ttf" && file.extension() != ".tte") + if(std::strcmp(filepath, "default") != 0 && file.extension() != ".ttf" && file.extension() != ".tte") { mlx::core::error::report(e_kind::error, "TTF loader : not a truetype font file '%s'", filepath); return; @@ -189,7 +189,7 @@ extern "C" void mlx_set_font_scale(void* mlx, void* win, char* filepath, float scale) { std::filesystem::path file(filepath); - if(file.extension() != ".ttf" && file.extension() != ".tte") + if(std::strcmp(filepath, "default") != 0 && file.extension() != ".ttf" && file.extension() != ".tte") { mlx::core::error::report(e_kind::error, "TTF loader : not a truetype font file '%s'", filepath); return; diff --git a/src/core/graphics.cpp b/src/core/graphics.cpp index 523ff3c..ec36a73 100644 --- a/src/core/graphics.cpp +++ b/src/core/graphics.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/02 15:13:55 by maldavid #+# #+# */ -/* Updated: 2023/12/10 22:20:38 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/14 17:14:30 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -51,11 +51,7 @@ namespace mlx sets[1] = _pixel_put_pipeline.getDescriptorSet(); vkCmdBindDescriptorSets(cmd_buff, VK_PIPELINE_BIND_POINT_GRAPHICS, _renderer->getPipeline().getPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr); _pixel_put_pipeline.render(*_renderer); - - sets[1] = _text_put_pipeline->getDescriptorSet(); - vkCmdBindDescriptorSets(cmd_buff, VK_PIPELINE_BIND_POINT_GRAPHICS, _renderer->getPipeline().getPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr); - _text_put_pipeline->render(); - + _text_put_pipeline->render(sets); _renderer->endFrame(); for(auto& data : _textures_to_render) diff --git a/src/core/graphics.inl b/src/core/graphics.inl index 0a472c3..54f00ee 100644 --- a/src/core/graphics.inl +++ b/src/core/graphics.inl @@ -47,14 +47,7 @@ namespace mlx void GraphicsSupport::texturePut(Texture* texture, int x, int y) { _textures_to_render.emplace_back(texture, x, y); - std::size_t hash = std::hash{}(_textures_to_render.back()); - _textures_to_render.back().hash = hash; - - auto it = std::find_if(_textures_to_render.begin(), _textures_to_render.end() - 1, [=](const TextureRenderData& rhs) - { - return rhs.hash == hash; - }); - + auto it = std::find(_textures_to_render.begin(), _textures_to_render.end() - 1, _textures_to_render.back()); if(it != _textures_to_render.end() - 1) _textures_to_render.erase(it); } diff --git a/src/renderer/descriptors/vk_descriptor_set.cpp b/src/renderer/descriptors/vk_descriptor_set.cpp index 28bc816..f0365a1 100644 --- a/src/renderer/descriptors/vk_descriptor_set.cpp +++ b/src/renderer/descriptors/vk_descriptor_set.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/01/23 18:40:44 by maldavid #+# #+# */ -/* Updated: 2023/12/07 20:00:13 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/14 16:45:11 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -42,7 +42,7 @@ namespace mlx #endif } - void DescriptorSet::writeDescriptor(int binding, UBO* ubo) noexcept + void DescriptorSet::writeDescriptor(int binding, UBO* ubo) const noexcept { auto device = Render_Core::get().getDevice().get(); @@ -66,7 +66,7 @@ namespace mlx } } - void DescriptorSet::writeDescriptor(int binding, VkImageView view, VkSampler sampler) noexcept + void DescriptorSet::writeDescriptor(int binding, VkImageView view, VkSampler sampler) const noexcept { auto device = Render_Core::get().getDevice().get(); diff --git a/src/renderer/descriptors/vk_descriptor_set.h b/src/renderer/descriptors/vk_descriptor_set.h index 270b46e..601032f 100644 --- a/src/renderer/descriptors/vk_descriptor_set.h +++ b/src/renderer/descriptors/vk_descriptor_set.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/01/23 18:39:36 by maldavid #+# #+# */ -/* Updated: 2023/12/08 19:09:31 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/14 17:12:49 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,10 +25,10 @@ namespace mlx public: void init(class Renderer* renderer, class DescriptorPool* pool, class DescriptorSetLayout* layout); - void writeDescriptor(int binding, class UBO* ubo) noexcept; - void writeDescriptor(int binding, VkImageView view, VkSampler sampler) noexcept; + void writeDescriptor(int binding, class UBO* ubo) const noexcept; + void writeDescriptor(int binding, VkImageView view, VkSampler sampler) const noexcept; - inline bool isInit() noexcept { return _pool != nullptr && _renderer != nullptr; } + inline bool isInit() const noexcept { return _pool != nullptr && _renderer != nullptr; } DescriptorSet duplicate(); diff --git a/src/renderer/font.cpp b/src/renderer/font.cpp index a75aadb..b053b8f 100644 --- a/src/renderer/font.cpp +++ b/src/renderer/font.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/12/11 22:06:09 by kbz_8 #+# #+# */ -/* Updated: 2023/12/12 23:57:53 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/14 19:11:41 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,7 +18,7 @@ constexpr const int RANGE = 1024; namespace mlx { - Font::Font(Renderer& renderer, const std::filesystem::path& path, float scale) : non_copyable(), _name(path.string()) + Font::Font(Renderer& renderer, const std::filesystem::path& path, float scale) : non_copyable(), _name(path.string()), _scale(scale) { std::vector tmp_bitmap(RANGE * RANGE); std::vector vulkan_bitmap(RANGE * RANGE * 4); @@ -47,20 +47,20 @@ namespace mlx vulkan_bitmap[j + 3] = tmp_bitmap[i]; } #ifdef DEBUG - _atlas.create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, std::string(name + "_font_altas").c_str(), true); + _atlas.create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, std::string(_name + "_font_altas").c_str(), true); #else _atlas.create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, nullptr, true); #endif _atlas.setDescriptor(renderer.getFragDescriptorSet().duplicate()); } - Font::Font(class Renderer& renderer, const std::string& name, const std::vector& ttf_data, float scale) + Font::Font(class Renderer& renderer, const std::string& name, const std::vector& ttf_data, float scale) : non_copyable(), _name(name), _scale(scale) { std::vector tmp_bitmap(RANGE * RANGE); std::vector vulkan_bitmap(RANGE * RANGE * 4); stbtt_pack_context pc; stbtt_PackBegin(&pc, tmp_bitmap.data(), RANGE, RANGE, RANGE, 1, nullptr); - stbtt_PackFontRange(&pc, ttf_data.data(), 0, 6.0, 32, 96, _cdata.data()); + stbtt_PackFontRange(&pc, ttf_data.data(), 0, scale, 32, 96, _cdata.data()); stbtt_PackEnd(&pc); for(int i = 0, j = 0; i < RANGE * RANGE; i++, j += 4) { @@ -70,7 +70,7 @@ namespace mlx vulkan_bitmap[j + 3] = tmp_bitmap[i]; } #ifdef DEBUG - _atlas.create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, std::string(name + "_font_altas").c_str(), true); + _atlas.create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, std::string(_name + "_font_altas").c_str(), true); #else _atlas.create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, nullptr, true); #endif diff --git a/src/renderer/font.h b/src/renderer/font.h index 8e3ba08..d25c4b7 100644 --- a/src/renderer/font.h +++ b/src/renderer/font.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/12/11 21:17:04 by kbz_8 #+# #+# */ -/* Updated: 2023/12/13 00:25:30 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/14 17:51:40 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,24 +17,29 @@ #include #include #include +#include namespace mlx { class Font : public non_copyable { public: + Font() = delete; Font(class Renderer& renderer, const std::filesystem::path& path, float scale); Font(class Renderer& renderer, const std::string& name, const std::vector& ttf_data, float scale); inline const std::string& getName() const { return _name; } + inline float getScale() const noexcept { return _scale; } inline const std::array& getCharData() const { return _cdata; } - inline VkDescriptorSet getDescriptorSet() noexcept { return _atlas.getSet(); } - inline bool operator==(const Font& rhs) { return rhs._name == _name; } + inline const TextureAtlas& getAtlas() const noexcept { return _atlas; } + inline bool operator==(const Font& rhs) const { return rhs._name == _name; } + inline bool operator!=(const Font& rhs) const { return rhs._name != _name; } ~Font(); private: std::array _cdata; TextureAtlas _atlas; std::string _name; + float _scale = 0; }; } @@ -45,7 +50,9 @@ namespace std { std::size_t operator()(const mlx::Font& f) const noexcept { - return std::hash()(f.getName()); + std::size_t hash = 0; + mlx::hashCombine(hash, f.getName(), f.getScale()); + return hash; } }; } diff --git a/src/renderer/images/texture.h b/src/renderer/images/texture.h index 695e580..7158d2a 100644 --- a/src/renderer/images/texture.h +++ b/src/renderer/images/texture.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/03/08 02:24:58 by maldavid #+# #+# */ -/* Updated: 2023/12/08 19:10:09 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/14 16:28:07 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -76,16 +76,4 @@ namespace mlx }; } -namespace std -{ - template <> - struct hash - { - size_t operator()(const mlx::TextureRenderData& td) const noexcept - { - return std::hash()(td.texture) + std::hash()(td.x) + std::hash()(td.y); - } - }; -} - #endif diff --git a/src/renderer/images/texture_atlas.cpp b/src/renderer/images/texture_atlas.cpp index f129baf..be611bc 100644 --- a/src/renderer/images/texture_atlas.cpp +++ b/src/renderer/images/texture_atlas.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/07 16:40:09 by maldavid #+# #+# */ -/* Updated: 2023/11/14 05:36:46 by maldavid ### ########.fr */ +/* Updated: 2023/12/14 16:39:54 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -36,7 +36,7 @@ namespace mlx } } - void TextureAtlas::render(Renderer& renderer, int x, int y, uint32_t ibo_size) + void TextureAtlas::render(Renderer& renderer, int x, int y, uint32_t ibo_size) const { auto cmd = renderer.getActiveCmdBuffer().get(); diff --git a/src/renderer/images/texture_atlas.h b/src/renderer/images/texture_atlas.h index c571e27..1cb8c09 100644 --- a/src/renderer/images/texture_atlas.h +++ b/src/renderer/images/texture_atlas.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/07 16:36:33 by maldavid #+# #+# */ -/* Updated: 2023/12/08 19:10:22 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/14 17:12:54 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -26,12 +26,12 @@ namespace mlx TextureAtlas() = default; void create(uint8_t* pixels, uint32_t width, uint32_t height, VkFormat format, const char* name, bool dedicated_memory = false); - void render(class Renderer& renderer, int x, int y, uint32_t ibo_size); + void render(class Renderer& renderer, int x, int y, uint32_t ibo_size) const; void destroy() noexcept override; inline void setDescriptor(DescriptorSet&& set) noexcept { _set = set; } inline VkDescriptorSet getSet() noexcept { return _set.isInit() ? _set.get() : VK_NULL_HANDLE; } - inline void updateSet(int binding) noexcept { _set.writeDescriptor(binding, getImageView(), getSampler()); } + inline void updateSet(int binding) const noexcept { _set.writeDescriptor(binding, getImageView(), getSampler()); } ~TextureAtlas() = default; diff --git a/src/renderer/images/vk_image.h b/src/renderer/images/vk_image.h index 2498c90..a55a2a4 100644 --- a/src/renderer/images/vk_image.h +++ b/src/renderer/images/vk_image.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/01/25 11:54:21 by maldavid #+# #+# */ -/* Updated: 2023/12/08 19:10:38 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/14 16:44:40 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -50,10 +50,10 @@ namespace mlx inline VkImage get() noexcept { return _image; } inline VkImage operator()() noexcept { return _image; } - inline VkImageView getImageView() noexcept { return _image_view; } - inline VkFormat getFormat() noexcept { return _format; } - inline VkImageTiling getTiling() noexcept { return _tiling; } - inline VkSampler getSampler() noexcept { return _sampler; } + inline VkImageView getImageView() const noexcept { return _image_view; } + inline VkFormat getFormat() const noexcept { return _format; } + inline VkImageTiling getTiling() const noexcept { return _tiling; } + inline VkSampler getSampler() const noexcept { return _sampler; } inline uint32_t getWidth() const noexcept { return _width; } inline uint32_t getHeight() const noexcept { return _height; } diff --git a/src/renderer/pixel_put.cpp b/src/renderer/pixel_put.cpp index 90e4fe1..7dcff20 100644 --- a/src/renderer/pixel_put.cpp +++ b/src/renderer/pixel_put.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/03/31 15:14:50 by maldavid #+# #+# */ -/* Updated: 2023/12/10 22:33:59 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/14 18:26:03 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,14 +22,14 @@ namespace mlx _buffer.create(Buffer::kind::dynamic, sizeof(uint32_t) * (width * height), VK_BUFFER_USAGE_TRANSFER_SRC_BIT, "__mlx_pixel_put_pipeline_texture"); _buffer.mapMem(&_buffer_map); - _cpu_map = std::vector(height * width, 0); + _cpu_map = std::vector(height * width + 1, 0); _width = width; _height = height; } - void PixelPutPipeline::setPixel(uint32_t x, uint32_t y, uint32_t color) noexcept + void PixelPutPipeline::setPixel(int x, int y, uint32_t color) noexcept { - if(x > _width || y > _height) + if(x < 0 || y < 0 || x > static_cast(_width) || y > static_cast(_height)) return; _cpu_map[(y * _width) + x] = color; _has_been_modified = true; diff --git a/src/renderer/pixel_put.h b/src/renderer/pixel_put.h index bd51d41..eddae2f 100644 --- a/src/renderer/pixel_put.h +++ b/src/renderer/pixel_put.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/03/31 13:18:50 by maldavid #+# #+# */ -/* Updated: 2023/12/08 19:11:43 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/14 18:24:58 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -26,7 +26,7 @@ namespace mlx void init(uint32_t width, uint32_t height, class Renderer& renderer) noexcept; - void setPixel(uint32_t x, uint32_t y, uint32_t color) noexcept; + void setPixel(int x, int y, uint32_t color) noexcept; void present() noexcept; void render(class Renderer& renderer) noexcept; inline VkDescriptorSet getDescriptorSet() noexcept { return _texture.getSet(); } diff --git a/src/renderer/text_pipeline.cpp b/src/renderer/text_pipeline.cpp index a6fae69..173e6f9 100644 --- a/src/renderer/text_pipeline.cpp +++ b/src/renderer/text_pipeline.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/06 16:41:13 by maldavid #+# #+# */ -/* Updated: 2023/12/14 00:06:29 by maldavid ### ########.fr */ +/* Updated: 2023/12/14 17:49:37 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -83,7 +83,10 @@ namespace mlx void TextPutPipeline::loadFont(const std::filesystem::path& filepath, float scale) { - _font_in_use = &const_cast(*_font_set.emplace(*_renderer, filepath, scale).first); + if(filepath.string() == "default") // we're sure it is already loaded + _font_in_use = &const_cast(*_font_set.emplace(*_renderer, "default", dogica_ttf, scale).first); + else + _font_in_use = &const_cast(*_font_set.emplace(*_renderer, filepath, scale).first); } void TextPutPipeline::put(int x, int y, int color, std::string str) @@ -91,16 +94,28 @@ namespace mlx auto res = _drawlist.emplace(std::move(str), color, x, y); if(res.second) const_cast(*res.first).init(_library, _font_in_use); + else + { + auto text_ptr = _library.getTextData(res.first->id); + if(*_font_in_use != text_ptr->getFontInUse()) + { + _library.removeTextFromLibrary(res.first->id); + const_cast(*res.first).init(_library, _font_in_use); + } + } } - void TextPutPipeline::render() + void TextPutPipeline::render(std::array& sets) { - _atlas.updateSet(0); for(auto& draw : _drawlist) { std::shared_ptr draw_data = _library.getTextData(draw.id); + const TextureAtlas& atlas = draw_data->getFontInUse().getAtlas(); draw_data->bind(*_renderer); - _atlas.render(*_renderer, draw.x, draw.y, draw_data->getIBOsize()); + atlas.updateSet(0); + sets[1] = const_cast(atlas).getSet(); + vkCmdBindDescriptorSets(_renderer->getActiveCmdBuffer().get(), VK_PIPELINE_BIND_POINT_GRAPHICS, _renderer->getPipeline().getPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr); + atlas.render(*_renderer, draw.x, draw.y, draw_data->getIBOsize()); } } diff --git a/src/renderer/text_pipeline.h b/src/renderer/text_pipeline.h index db6f405..efb5058 100644 --- a/src/renderer/text_pipeline.h +++ b/src/renderer/text_pipeline.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/06 16:24:11 by maldavid #+# #+# */ -/* Updated: 2023/12/13 00:24:21 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/14 17:39:51 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,6 +21,7 @@ #include #include #include +#include namespace mlx { @@ -35,6 +36,7 @@ namespace mlx TextDrawData(std::string text, int _color, int _x, int _y); void init(TextLibrary& library, Font* const font) noexcept; bool operator==(const TextDrawData& rhs) const { return text == rhs.text && x == rhs.x && y == rhs.y && color == rhs.color; } + TextDrawData() = default; }; } @@ -45,7 +47,9 @@ namespace std { std::size_t operator()(const mlx::TextDrawData& d) const noexcept { - return std::hash()(d.text) + std::hash()(d.x) + std::hash()(d.y) + std::hash()(d.color); + std::size_t hash = 0; + mlx::hashCombine(hash, d.text, d.x, d.y, d.color); + return hash; } }; } @@ -59,9 +63,9 @@ namespace mlx void init(Renderer* renderer) noexcept; void put(int x, int y, int color, std::string str); - inline void clear() { _drawlist.clear(); } + inline void clear() { _drawlist.clear(); _library.clearLibrary(); } void loadFont(const std::filesystem::path& filepath, float scale); - void render(); + void render(std::array& sets); void destroy() noexcept; ~TextPutPipeline() = default; diff --git a/src/utils/combine_hash.h b/src/utils/combine_hash.h new file mode 100644 index 0000000..48a33a3 --- /dev/null +++ b/src/utils/combine_hash.h @@ -0,0 +1,32 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* combine_hash.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maldavid +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/14 16:16:06 by maldavid #+# #+# */ +/* Updated: 2023/12/14 16:47:39 by maldavid ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef __MLX_HASH__ +#define __MLX_HASH__ + +#include +#include + +namespace mlx +{ + inline void hashCombine([[maybe_unused]] std::size_t& seed) noexcept {} + + template + inline void hashCombine(std::size_t& seed, const T& v, Rest... rest) + { + std::hash hasher; + seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + hashCombine(seed, rest...); + } +} + +#endif diff --git a/src/utils/dogica_ttf.h b/src/utils/dogica_ttf.h index a2907d3..e890ab3 100644 --- a/src/utils/dogica_ttf.h +++ b/src/utils/dogica_ttf.h @@ -6,16 +6,18 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/11 16:20:25 by maldavid #+# #+# */ -/* Updated: 2023/12/08 19:13:00 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/14 16:54:12 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef __MLX_DOGICA_TTF__ #define __MLX_DOGICA_TTF__ +#include + constexpr const unsigned int dogica_ttf_len = 33860; -constexpr const unsigned char dogica_ttf[dogica_ttf_len] = { +static const std::vector dogica_ttf = { 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x80, 0x00, 0x03, 0x00, 0x60, 0x46, 0x46, 0x54, 0x4d, 0x8f, 0xe1, 0x5b, 0x60, 0x00, 0x00, 0x84, 0x28, 0x00, 0x00, 0x00, 0x1c, 0x47, 0x44, 0x45, 0x46, 0x00, 0x15, 0x00, 0x14, diff --git a/test/main.c b/test/main.c index 12e13a2..c331f51 100644 --- a/test/main.c +++ b/test/main.c @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 17:55:21 by maldavid #+# #+# */ -/* Updated: 2023/12/08 18:08:13 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/14 18:49:01 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -32,22 +32,21 @@ int update(void *param) mlx = (t_mlx *)param; mlx_put_image_to_window(mlx->mlx, mlx->win, mlx->logo, 100, 100); mlx_put_image_to_window(mlx->mlx, mlx->win, mlx->img, 150, 60); + if (i == 0) + mlx_set_font_scale(mlx->mlx, mlx->win, "font.ttf", 16.f); mlx_string_put(mlx->mlx, mlx->win, 20, 50, 0xFFFFFFFF, "that's a text"); j = 0; k = 0; - while (j < 400) + while (j++ < 400) { mlx_pixel_put(mlx->mlx, mlx->win, j, j, 0xFFFF0000 + k); mlx_pixel_put(mlx->mlx, mlx->win, 399 - j, j, 0xFF0000FF); - if (k < 255) - k++; - j++; + k += (k < 255); } if (++i == 5000) - { mlx_clear_window(mlx->mlx, mlx->win); - mlx_set_font_scale(mlx->mlx, mlx->win, "font.ttf", 16.f); - } + if (i == 7000) + mlx_set_font_scale(mlx->mlx, mlx->win, "default", 16.f); return (0); } diff --git a/valgrind.supp b/valgrind.supp index 3e26281..d746267 100644 --- a/valgrind.supp +++ b/valgrind.supp @@ -54,7 +54,16 @@ fun:*alloc obj:* ... - fun:_dl_* + fun:dl_* + ... +} +{ + name + Memcheck:Addr8 + fun:* + obj:* + ... + fun:dl_* ... } { From 8e33b2fa309f459a534f38f8483234d4e98b3da4 Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Fri, 15 Dec 2023 18:08:22 +0100 Subject: [PATCH 5/6] updating README --- README.md | 14 ++++++++++++++ src/renderer/core/render_core.cpp | 4 +++- src/renderer/core/vk_instance.cpp | 6 ++---- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 483b2f5..55b495f 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,20 @@ ###### 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 + +### 🏁 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 +Designed to be totally cross-platform, it can run on any SDL2-supported platform that supports Vulkan (even the Nintendo Switch ! theoretically... ). + +### 🗿 Close to the old minilibx +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. + +### 📖 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). + ## 🖥️ Installation ### Dependencies diff --git a/src/renderer/core/render_core.cpp b/src/renderer/core/render_core.cpp index c708fd9..3849a8a 100644 --- a/src/renderer/core/render_core.cpp +++ b/src/renderer/core/render_core.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/12/17 23:33:34 by maldavid #+# #+# */ -/* Updated: 2023/12/12 15:45:26 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/15 15:21:26 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,8 +16,10 @@ #define VK_USE_PLATFORM_WIN32_KHR #elif defined(__APPLE__) || defined(__MACH__) #define VK_USE_PLATFORM_MACOS_MVK + #define VK_USE_PLATFORM_METAL_EXT #else #define VK_USE_PLATFORM_XLIB_KHR + #define VK_USE_PLATFORM_WAYLAND_KHR #endif #include "render_core.h" diff --git a/src/renderer/core/vk_instance.cpp b/src/renderer/core/vk_instance.cpp index 9ee7914..3a51c75 100644 --- a/src/renderer/core/vk_instance.cpp +++ b/src/renderer/core/vk_instance.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/08 19:04:21 by maldavid #+# #+# */ -/* Updated: 2023/12/12 15:46:06 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/15 16:20:26 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,10 +21,8 @@ namespace mlx { VkApplicationInfo appInfo{}; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; - appInfo.pApplicationName = "MacroLibX"; - appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); appInfo.pEngineName = "MacroLibX"; - appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); + appInfo.engineVersion = VK_MAKE_VERSION(1, 2, 1); appInfo.apiVersion = VK_API_VERSION_1_2; VkInstanceCreateInfo createInfo{}; From b28b144edb8d8bdebdf117dad46379f9fa7efd59 Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Fri, 15 Dec 2023 21:08:46 +0100 Subject: [PATCH 6/6] fixing issue when destroying an image in the loop hook, begenning single time command buffers manager --- src/core/application.cpp | 4 +- src/core/application.inl | 10 +++- src/core/graphics.cpp | 4 +- .../command/single_time_cmd_manager.cpp | 47 +++++++++++++++++++ .../command/single_time_cmd_manager.h | 44 +++++++++++++++++ src/renderer/command/vk_cmd_buffer.h | 3 +- src/renderer/core/render_core.cpp | 4 +- src/renderer/core/render_core.h | 5 +- src/renderer/core/vk_fence.cpp | 8 +++- src/renderer/core/vk_fence.h | 4 +- src/renderer/images/vk_image.h | 4 +- test/main.c | 2 +- 12 files changed, 127 insertions(+), 12 deletions(-) create mode 100644 src/renderer/command/single_time_cmd_manager.cpp create mode 100644 src/renderer/command/single_time_cmd_manager.h diff --git a/src/core/application.cpp b/src/core/application.cpp index 5072560..0a30f7b 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 22:10:52 by maldavid #+# #+# */ -/* Updated: 2023/12/11 19:46:13 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/15 20:51:41 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -61,7 +61,7 @@ namespace mlx::core void Application::destroyTexture(void* ptr) { - vkDeviceWaitIdle(Render_Core::get().getDevice().get()); + vkDeviceWaitIdle(Render_Core::get().getDevice().get()); // TODO : synchronize with another method than stopping all the GPU porcess Texture* texture = static_cast(ptr); texture->destroy(); } diff --git a/src/core/application.inl b/src/core/application.inl index 85fbd8f..3fd33c0 100644 --- a/src/core/application.inl +++ b/src/core/application.inl @@ -74,8 +74,16 @@ namespace mlx::core void Application::texturePut(void* win, void* img, int x, int y) { + if(img == nullptr) + { + core::error::report(e_kind::error, "wrong texture (NULL)"); + return; + } Texture* texture = static_cast(img); - _graphics[*static_cast(win)]->texturePut(texture, x, y); + if(!texture->isInit()) + core::error::report(e_kind::error, "trying to put a texture that has been destroyed"); + else + _graphics[*static_cast(win)]->texturePut(texture, x, y); } int Application::getTexturePixel(void* img, int x, int y) diff --git a/src/core/graphics.cpp b/src/core/graphics.cpp index ec36a73..bc4fd81 100644 --- a/src/core/graphics.cpp +++ b/src/core/graphics.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/02 15:13:55 by maldavid #+# #+# */ -/* Updated: 2023/12/14 17:14:30 by maldavid ### ########.fr */ +/* Updated: 2023/12/15 21:04:50 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -37,6 +37,8 @@ namespace mlx for(auto& data : _textures_to_render) { + if(!data.texture->isInit()) + continue; if(data.texture->getSet() == VK_NULL_HANDLE) data.texture->setDescriptor(_renderer->getFragDescriptorSet().duplicate()); if(!data.texture->hasBeenUpdated()) diff --git a/src/renderer/command/single_time_cmd_manager.cpp b/src/renderer/command/single_time_cmd_manager.cpp new file mode 100644 index 0000000..c64f445 --- /dev/null +++ b/src/renderer/command/single_time_cmd_manager.cpp @@ -0,0 +1,47 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* single_time_cmd_manager.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maldavid +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/15 19:57:49 by maldavid #+# #+# */ +/* Updated: 2023/12/15 20:21:54 by maldavid ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include +#include +#include + +namespace mlx +{ + SingleTimeCmdManager::SingleTimeCmdManager() : _buffers(MIN_POOL_SIZE) {} + + void SingleTimeCmdManager::init() noexcept + { + _pool.init(); + for(int i = 0; i < MIN_POOL_SIZE; i++) + _buffers.emplace_back().init(&_pool); + } + + void SingleTimeCmdManager::destroy() noexcept + { + std::for_each(_buffers.begin(), _buffers.end(), [](CmdBuffer& buf) + { + buf.destroy(); + }); + _pool.destroy(); + } + + CmdBuffer& SingleTimeCmdManager::getCmdBuffer() noexcept + { + for(CmdBuffer& buf : _buffers) + { + if(buf.isReadyToBeUsed()) + return buf; + } + _buffers.emplace_back().init(&_pool); + return _buffers.back(); + } +} diff --git a/src/renderer/command/single_time_cmd_manager.h b/src/renderer/command/single_time_cmd_manager.h new file mode 100644 index 0000000..a05dca3 --- /dev/null +++ b/src/renderer/command/single_time_cmd_manager.h @@ -0,0 +1,44 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* single_time_cmd_manager.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maldavid +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/15 18:25:57 by maldavid #+# #+# */ +/* Updated: 2023/12/15 19:59:40 by maldavid ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef __MLX_SINGLE_TIME_CMD_MANAGER__ +#define __MLX_SINGLE_TIME_CMD_MANAGER__ + +#include + +#include +#include + +namespace mlx +{ + class SingleTimeCmdManager + { + public: + SingleTimeCmdManager(); + + void init() noexcept; + void destroy() noexcept; + + inline CmdPool& getCmdPool() noexcept { return _pool; } + CmdBuffer& getCmdBuffer() noexcept; + + ~SingleTimeCmdManager() = default; + + inline static constexpr const uint8_t MIN_POOL_SIZE = 8; + + private: + std::vector _buffers; + CmdPool _pool; + }; +} + +#endif diff --git a/src/renderer/command/vk_cmd_buffer.h b/src/renderer/command/vk_cmd_buffer.h index eca0520..bc8e653 100644 --- a/src/renderer/command/vk_cmd_buffer.h +++ b/src/renderer/command/vk_cmd_buffer.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/06 18:25:42 by maldavid #+# #+# */ -/* Updated: 2023/12/08 19:07:11 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/15 20:19:42 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -31,6 +31,7 @@ namespace mlx void submitIdle() noexcept; inline void waitForExecution() noexcept { _fence.waitAndReset(); } 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; } diff --git a/src/renderer/core/render_core.cpp b/src/renderer/core/render_core.cpp index 3849a8a..fa615ff 100644 --- a/src/renderer/core/render_core.cpp +++ b/src/renderer/core/render_core.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/12/17 23:33:34 by maldavid #+# #+# */ -/* Updated: 2023/12/15 15:21:26 by maldavid ### ########.fr */ +/* Updated: 2023/12/15 20:32:01 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -97,6 +97,7 @@ namespace mlx volkLoadDevice(_device.get()); _queues.init(); _allocator.init(); + _cmd_manager.init(); _is_init = true; } @@ -107,6 +108,7 @@ namespace mlx vkDeviceWaitIdle(_device()); + _cmd_manager.destroy(); _allocator.destroy(); _device.destroy(); _layers.destroy(); diff --git a/src/renderer/core/render_core.h b/src/renderer/core/render_core.h index fe4efbc..a318ff4 100644 --- a/src/renderer/core/render_core.h +++ b/src/renderer/core/render_core.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/08 19:16:32 by maldavid #+# #+# */ -/* Updated: 2023/12/12 15:45:39 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/15 20:31:08 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,6 +16,7 @@ #include #include +#include #include "vk_queues.h" #include "vk_device.h" #include "vk_instance.h" @@ -57,11 +58,13 @@ namespace mlx inline Queues& getQueue() noexcept { return _queues; } inline GPUallocator& getAllocator() noexcept { return _allocator; } inline ValidationLayers& getLayers() noexcept { return _layers; } + inline CmdBuffer& getSingleTimeCmdBuffer() noexcept { return _cmd_manager.getCmdBuffer(); } ~Render_Core() = default; private: ValidationLayers _layers; + SingleTimeCmdManager _cmd_manager; Queues _queues; Device _device; Instance _instance; diff --git a/src/renderer/core/vk_fence.cpp b/src/renderer/core/vk_fence.cpp index 8061a6c..7b58f58 100644 --- a/src/renderer/core/vk_fence.cpp +++ b/src/renderer/core/vk_fence.cpp @@ -6,11 +6,12 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/02 17:53:06 by maldavid #+# #+# */ -/* Updated: 2023/12/12 15:50:48 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/15 20:31:29 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ #include +#include namespace mlx { @@ -38,6 +39,11 @@ namespace mlx vkResetFences(Render_Core::get().getDevice().get(), 1, &_fence); } + bool Fence::isReady() const noexcept + { + return vkGetFenceStatus(Render_Core::get().getDevice().get(), _fence) == VK_SUCCESS; + } + void Fence::destroy() noexcept { if(_fence != VK_NULL_HANDLE) diff --git a/src/renderer/core/vk_fence.h b/src/renderer/core/vk_fence.h index f50e223..ec5c8a1 100644 --- a/src/renderer/core/vk_fence.h +++ b/src/renderer/core/vk_fence.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/02 17:52:09 by maldavid #+# #+# */ -/* Updated: 2023/12/08 19:08:01 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/15 20:31:25 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,7 +15,6 @@ #include #include -#include namespace mlx { @@ -29,6 +28,7 @@ namespace mlx inline VkFence& get() noexcept { return _fence; } void wait() noexcept; void reset() noexcept; + bool isReady() const noexcept; inline void waitAndReset() noexcept { wait(); reset(); } void destroy() noexcept; diff --git a/src/renderer/images/vk_image.h b/src/renderer/images/vk_image.h index a55a2a4..f1cc20d 100644 --- a/src/renderer/images/vk_image.h +++ b/src/renderer/images/vk_image.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/01/25 11:54:21 by maldavid #+# #+# */ -/* Updated: 2023/12/14 16:44:40 by maldavid ### ########.fr */ +/* Updated: 2023/12/15 21:07:34 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +57,7 @@ namespace mlx inline VkSampler getSampler() const noexcept { return _sampler; } inline uint32_t getWidth() const noexcept { return _width; } inline uint32_t getHeight() const noexcept { return _height; } + inline bool isInit() const noexcept { return _image != VK_NULL_HANDLE; } virtual ~Image() = default; diff --git a/test/main.c b/test/main.c index 3da1085..8be11b1 100644 --- a/test/main.c +++ b/test/main.c @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 17:55:21 by maldavid #+# #+# */ -/* Updated: 2023/12/14 18:49:01 by maldavid ### ########.fr */ +/* Updated: 2023/12/15 21:08:07 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */