still working on code refactoring

This commit is contained in:
2024-04-23 22:59:33 +02:00
parent ace4c98945
commit 1d9a51e4f7
16 changed files with 560 additions and 518 deletions

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/01/23 18:39:36 by maldavid #+# #+# */ /* Created: 2023/01/23 18:39:36 by maldavid #+# #+# */
/* Updated: 2024/04/23 19:49:02 by maldavid ### ########.fr */ /* Updated: 2024/04/23 22:14:48 by maldavid ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -30,11 +30,15 @@ namespace mlx
inline bool IsInit() const noexcept { return m_pool != nullptr && m_renderer != nullptr; } inline bool IsInit() const noexcept { return m_pool != nullptr && m_renderer != nullptr; }
void Bind() noexcept;
DescriptorSet Duplicate(); DescriptorSet Duplicate();
VkDescriptorSet& operator()() noexcept; VkDescriptorSet& operator()() noexcept;
VkDescriptorSet& Get() noexcept; VkDescriptorSet& Get() noexcept;
inline const DescriptorSetLayout& GetLayout() const noexcept { return m_layout; }
inline const std::array<VkDescriptorSet, MAX_FRAMES_IN_FLIGHT>& GetAllFramesDescriptorSets() const { return m_desc_set; } inline const std::array<VkDescriptorSet, MAX_FRAMES_IN_FLIGHT>& GetAllFramesDescriptorSets() const { return m_desc_set; }
void Destroy() noexcept; void Destroy() noexcept;
@@ -42,7 +46,7 @@ namespace mlx
~DescriptorSet() = default; ~DescriptorSet() = default;
private: private:
DescriptorSetLayout p_layout; DescriptorSetLayout m_layout;
std::array<VkDescriptorSet, MAX_FRAMES_IN_FLIGHT> m_desc_set; std::array<VkDescriptorSet, MAX_FRAMES_IN_FLIGHT> m_desc_set;
NonOwningPtr<class DescriptorPool> p_pool; NonOwningPtr<class DescriptorPool> p_pool;
NonOwningPtr<class Renderer> p_renderer; NonOwningPtr<class Renderer> p_renderer;

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/01/23 18:36:22 by maldavid #+# #+# */ /* Created: 2023/01/23 18:36:22 by maldavid #+# #+# */
/* Updated: 2024/04/23 19:50:50 by maldavid ### ########.fr */ /* Updated: 2024/04/23 22:15:01 by maldavid ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -23,8 +23,8 @@ namespace mlx
void Init(std::vector<std::pair<int, VkDescriptorType>> binds, VkShaderStageFlagBits stage); void Init(std::vector<std::pair<int, VkDescriptorType>> binds, VkShaderStageFlagBits stage);
void Destroy() noexcept; void Destroy() noexcept;
inline VkDescriptorSetLayout& operator()() noexcept { return m_layout; } inline VkDescriptorSetLayout operator()() const noexcept { return m_layout; }
inline VkDescriptorSetLayout& Get() noexcept { return m_layout; } inline VkDescriptorSetLayout Get() const noexcept { return m_layout; }
inline const std::vector<std::pair<int, VkDescriptorType>>& GetBindings() const noexcept { return m_bindings; } inline const std::vector<std::pair<int, VkDescriptorType>>& GetBindings() const noexcept { return m_bindings; }
~DescriptorSetLayout() = default; ~DescriptorSetLayout() = default;

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/11 01:00:13 by maldavid #+# #+# */ /* Created: 2024/01/11 01:00:13 by maldavid #+# #+# */
/* Updated: 2024/03/28 22:13:23 by maldavid ### ########.fr */ /* Updated: 2024/04/23 22:08:02 by maldavid ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -27,11 +27,11 @@ namespace mlx
TextureRenderDescriptor(NonOwningPtr<Texture> _texture, int _x, int _y) : texture(_texture), x(_x), y(_y) {} TextureRenderDescriptor(NonOwningPtr<Texture> _texture, int _x, int _y) : texture(_texture), x(_x), y(_y) {}
inline bool operator==(const TextureRenderDescriptor& rhs) const { return texture == rhs.texture && x == rhs.x && y == rhs.y; } inline bool operator==(const TextureRenderDescriptor& rhs) const { return texture == rhs.texture && x == rhs.x && y == rhs.y; }
inline void Render(std::array<VkDescriptorSet, 2>& sets, class Renderer& renderer) override inline void Render(class Renderer& renderer) override
{ {
if(!texture->IsInit()) if(!texture->IsInit())
return; return;
texture->Render(sets, renderer, x, y); texture->Render(renderer, x, y);
} }
inline void ResetUpdate() override inline void ResetUpdate() override
{ {

View File

@@ -1,12 +1,12 @@
/* ************************************************************************** */ /* ************************************************************************** */
/* */ /* */
/* ::: :::::::: */ /* ::: :::::::: */
/* TextureManager.h :+: :+: :+: */ /* TextureRegistry.h :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/11 00:56:15 by maldavid #+# #+# */ /* Created: 2024/01/11 00:56:15 by maldavid #+# #+# */
/* Updated: 2024/04/03 16:24:51 by maldavid ### ########.fr */ /* Updated: 2024/04/23 22:10:08 by maldavid ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -17,48 +17,23 @@
namespace mlx namespace mlx
{ {
class TextureManager class TextureRegistry
{ {
public: public:
TextureManager() = default; TextureRegistry() = default;
inline void Clear() { m_texture_descriptors.clear(); } inline void Clear();
inline std::pair<NonOwningPtr<DrawableResource>, bool> RegisterTexture(NonOwningPtr<Texture> texture, int x, int y);
inline bool IsTextureKnown(NonOwningPtr<Texture> texture) noexcept;
inline void EraseTextures(NonOwningPtr<Texture> texture);
inline std::pair<NonOwningPtr<DrawableResource>, bool> RegisterTexture(NonOwningPtr<Texture> texture, int x, int y) ~TextureRegistry() = default;
{
MLX_PROFILE_FUNCTION();
auto res = m_texture_descriptors.emplace(texture, x, y);
return std::make_pair(static_cast<DrawableResource*>(&const_cast<TextureRenderDescriptor&>(*res.first)), res.second);
}
inline bool IsTextureKnown(NonOwningPtr<Texture> texture) noexcept
{
MLX_PROFILE_FUNCTION();
for(const auto& desc : m_texture_descriptors)
{
if(desc.texture == texture)
return true;
}
return false;
}
inline void EraseTextures(NonOwningPtr<Texture> texture)
{
MLX_PROFILE_FUNCTION();
for(auto it = m_texture_descriptors.begin(); it != m_texture_descriptors.end();)
{
if(it->texture == texture)
it = m_texture_descriptors.erase(it);
else
++it;
}
}
~TextureManager() = default;
private: private:
std::unordered_set<TextureRenderDescriptor> m_texture_descriptors; std::unordered_set<TextureRenderDescriptor> m_texture_descriptors;
}; };
} }
#include <Renderer/Image/TextureRegistry.inl>
#endif #endif

View File

@@ -0,0 +1,52 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* TextureRegistry.inl :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/23 22:08:46 by maldavid #+# #+# */
/* Updated: 2024/04/23 22:11:09 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#pragma once
#include <Renderer/Images/TextureRegistry.h>
namespace mlx
{
void TextureRegistry::Clear()
{
m_texture_descriptors.clear();
}
std::pair<NonOwningPtr<DrawableResource>, bool> TextureRegistry::RegisterTexture(NonOwningPtr<Texture> texture, int x, int y)
{
MLX_PROFILE_FUNCTION();
auto res = m_texture_descriptors.emplace(texture, x, y);
return std::make_pair(static_cast<DrawableResource*>(&const_cast<TextureRenderDescriptor&>(*res.first)), res.second);
}
bool TextureRegistry::IsTextureKnown(NonOwningPtr<Texture> texture) noexcept
{
MLX_PROFILE_FUNCTION();
for(const auto& desc : m_texture_descriptors)
{
if(desc.texture == texture)
return true;
}
return false;
}
void TextureRegistry::EraseTextures(NonOwningPtr<Texture> texture)
{
MLX_PROFILE_FUNCTION();
for(auto it = m_texture_descriptors.begin(); it != m_texture_descriptors.end();)
{
if(it->texture == texture)
it = m_texture_descriptors.erase(it);
else
++it;
}
}
}

View File

@@ -6,13 +6,14 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2022/12/18 17:14:45 by maldavid #+# #+# */ /* Created: 2022/12/18 17:14:45 by maldavid #+# #+# */
/* Updated: 2024/03/28 22:36:05 by maldavid ### ########.fr */ /* Updated: 2024/04/23 22:25:13 by maldavid ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#ifndef __RENDERER__ #ifndef __RENDERER__
#define __RENDERER__ #define __RENDERER__
#include <Renderer/Vertex.h>
#include <Renderer/Buffers/UniformBuffer.h> #include <Renderer/Buffers/UniformBuffer.h>
#include <Renderer/Core/Surface.h> #include <Renderer/Core/Surface.h>
#include <Renderer/Core/RenderCore.h> #include <Renderer/Core/RenderCore.h>
@@ -28,47 +29,6 @@
namespace mlx namespace mlx
{ {
struct Vertex
{
glm::vec2 pos;
glm::vec4 color;
glm::vec2 uv;
Vertex(glm::vec2 _pos, glm::vec4 _color, glm::vec2 _uv) : pos(std::move(_pos)), color(std::move(_color)), uv(std::move(_uv)) {}
static VkVertexInputBindingDescription GetBindingDescription()
{
VkVertexInputBindingDescription binding_description{};
binding_description.binding = 0;
binding_description.stride = sizeof(Vertex);
binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
return binding_description;
}
static std::array<VkVertexInputAttributeDescription, 3> GetAttributeDescriptions()
{
std::array<VkVertexInputAttributeDescription, 3> attribute_descriptions;
attribute_descriptions[0].binding = 0;
attribute_descriptions[0].location = 0;
attribute_descriptions[0].format = VK_FORMAT_R32G32_SFLOAT;
attribute_descriptions[0].offset = offsetof(Vertex, pos);
attribute_descriptions[1].binding = 0;
attribute_descriptions[1].location = 1;
attribute_descriptions[1].format = VK_FORMAT_R32G32B32A32_SFLOAT;
attribute_descriptions[1].offset = offsetof(Vertex, color);
attribute_descriptions[2].binding = 0;
attribute_descriptions[2].location = 2;
attribute_descriptions[2].format = VK_FORMAT_R32G32_SFLOAT;
attribute_descriptions[2].offset = offsetof(Vertex, uv);
return attribute_descriptions;
}
};
class Renderer class Renderer
{ {
public: public:
@@ -96,8 +56,6 @@ namespace mlx
inline FrameBuffer& GetFrameBuffer(int i) noexcept { return m_framebuffers[i]; } inline FrameBuffer& GetFrameBuffer(int i) noexcept { return m_framebuffers[i]; }
inline DescriptorSet& GetVertDescriptorSet() noexcept { return m_vert_set; } inline DescriptorSet& GetVertDescriptorSet() noexcept { return m_vert_set; }
inline DescriptorSet& GetFragDescriptorSet() noexcept { return m_frag_set; } inline DescriptorSet& GetFragDescriptorSet() noexcept { return m_frag_set; }
inline DescriptorSetLayout& GetVertDescriptorSetLayout() noexcept { return m_vert_layout; }
inline DescriptorSetLayout& GetFragDescriptorSetLayout() noexcept { return m_frag_layout; }
inline std::uint32_t GetActiveImageIndex() noexcept { return m_current_frame_index; } inline std::uint32_t GetActiveImageIndex() noexcept { return m_current_frame_index; }
inline std::uint32_t GetImageIndex() noexcept { return m_image_index; } inline std::uint32_t GetImageIndex() noexcept { return m_image_index; }
@@ -117,9 +75,6 @@ namespace mlx
std::array<Semaphore, MAX_FRAMES_IN_FLIGHT> m_semaphores; std::array<Semaphore, MAX_FRAMES_IN_FLIGHT> m_semaphores;
std::vector<FrameBuffer> m_framebuffers; std::vector<FrameBuffer> m_framebuffers;
DescriptorSetLayout m_vert_layout;
DescriptorSetLayout m_frag_layout;
DescriptorSet m_vert_set; DescriptorSet m_vert_set;
DescriptorSet m_frag_set; DescriptorSet m_frag_set;

60
runtime/Includes/Renderer/Vertex.h git.filemode.normal_file
View File

@@ -0,0 +1,60 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* Vertex.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/23 22:24:33 by maldavid #+# #+# */
/* Updated: 2024/04/23 22:25:01 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef __MLX_RENDERER_VERTEX__
#define __MLX_RENDERER_VERTEX__
namespace mlx
{
struct Vertex
{
glm::vec2 pos;
glm::vec4 color;
glm::vec2 uv;
Vertex(glm::vec2 _pos, glm::vec4 _color, glm::vec2 _uv) : pos(std::move(_pos)), color(std::move(_color)), uv(std::move(_uv)) {}
static VkVertexInputBindingDescription GetBindingDescription()
{
VkVertexInputBindingDescription binding_description{};
binding_description.binding = 0;
binding_description.stride = sizeof(Vertex);
binding_description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
return binding_description;
}
static std::array<VkVertexInputAttributeDescription, 3> GetAttributeDescriptions()
{
std::array<VkVertexInputAttributeDescription, 3> attribute_descriptions;
attribute_descriptions[0].binding = 0;
attribute_descriptions[0].location = 0;
attribute_descriptions[0].format = VK_FORMAT_R32G32_SFLOAT;
attribute_descriptions[0].offset = offsetof(Vertex, pos);
attribute_descriptions[1].binding = 0;
attribute_descriptions[1].location = 1;
attribute_descriptions[1].format = VK_FORMAT_R32G32B32A32_SFLOAT;
attribute_descriptions[1].offset = offsetof(Vertex, color);
attribute_descriptions[2].binding = 0;
attribute_descriptions[2].location = 2;
attribute_descriptions[2].format = VK_FORMAT_R32G32_SFLOAT;
attribute_descriptions[2].offset = offsetof(Vertex, uv);
return attribute_descriptions;
}
};
}
#endif

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/01/23 18:40:44 by maldavid #+# #+# */ /* Created: 2023/01/23 18:40:44 by maldavid #+# #+# */
/* Updated: 2024/04/23 19:50:06 by maldavid ### ########.fr */ /* Updated: 2024/04/23 21:17:39 by maldavid ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -24,9 +24,9 @@ namespace mlx
void DescriptorSet::Init(NonOwningPtr<Renderer> renderer, NonOwningPtr<DescriptorPool> pool, DescriptorSetLayout layout) void DescriptorSet::Init(NonOwningPtr<Renderer> renderer, NonOwningPtr<DescriptorPool> pool, DescriptorSetLayout layout)
{ {
MLX_PROFILE_FUNCTION(); MLX_PROFILE_FUNCTION();
m_renderer = renderer; p_renderer = renderer;
m_layout = layout; m_layout = layout;
m_pool = pool; p_pool = pool;
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
m_desc_set[i] = pool->AllocateDescriptorSet(layout); m_desc_set[i] = pool->AllocateDescriptorSet(layout);
@@ -79,29 +79,34 @@ namespace mlx
vkUpdateDescriptorSets(device, 1, &descriptor_write, 0, nullptr); vkUpdateDescriptorSets(device, 1, &descriptor_write, 0, nullptr);
} }
void DescriptorSet::Bind() noexcept
{
vkCmdBindDescriptorSets(p_renderer->GetActiveCmdBuffer().Get(), VK_PIPELINE_BIND_POINT_GRAPHICS, p_renderer->GetPipeline().GetPipelineLayout(), 0, 1, m_desc_set[p_renderer->GetActiveImageIndex()], 0, nullptr);
}
DescriptorSet DescriptorSet::Duplicate() DescriptorSet DescriptorSet::Duplicate()
{ {
MLX_PROFILE_FUNCTION(); MLX_PROFILE_FUNCTION();
DescriptorSet set; DescriptorSet set;
set.Init(m_renderer, &RenderCore::Get().GetDescriptorPool(), m_layout); set.Init(p_renderer, &RenderCore::Get().GetDescriptorPool(), m_layout);
return set; return set;
} }
VkDescriptorSet& DescriptorSet::operator()() noexcept VkDescriptorSet& DescriptorSet::operator()() noexcept
{ {
return m_desc_set[m_renderer->GetActiveImageIndex()]; return m_desc_set[p_renderer->GetActiveImageIndex()];
} }
VkDescriptorSet& DescriptorSet::Get() noexcept VkDescriptorSet& DescriptorSet::Get() noexcept
{ {
return m_desc_set[m_renderer->GetActiveImageIndex()]; return m_desc_set[p_renderer->GetActiveImageIndex()];
} }
void DescriptorSet::Destroy() noexcept void DescriptorSet::Destroy() noexcept
{ {
MLX_PROFILE_FUNCTION(); MLX_PROFILE_FUNCTION();
if(m_pool != nullptr && RenderCore::Get().IsInit()) // checks if the render core is still init (it should always be init but just in case) if(p_pool != nullptr && RenderCore::Get().IsInit()) // checks if the render core is still init (it should always be init but just in case)
m_pool->FreeDescriptor(*this); p_pool->FreeDescriptor(*this);
for(auto& set : m_desc_set) for(auto& set : m_desc_set)
{ {
if(set != VK_NULL_HANDLE) if(set != VK_NULL_HANDLE)

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/03/31 18:03:35 by maldavid #+# #+# */ /* Created: 2023/03/31 18:03:35 by maldavid #+# #+# */
/* Updated: 2024/04/23 20:59:20 by maldavid ### ########.fr */ /* Updated: 2024/04/23 21:52:23 by maldavid ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -27,30 +27,30 @@
namespace mlx namespace mlx
{ {
void Texture::create(std::uint8_t* pixels, std::uint32_t width, std::uint32_t height, VkFormat format, const char* name, bool dedicated_memory) void Texture::Create(std::uint8_t* pixels, std::uint32_t width, std::uint32_t height, VkFormat format, const char* name, bool dedicated_memory)
{ {
MLX_PROFILE_FUNCTION(); MLX_PROFILE_FUNCTION();
Image::create(width, height, format, TILING, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, name, dedicated_memory); Image::Create(width, height, format, TILING, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, name, dedicated_memory);
Image::createImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT); Image::CreateImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT);
Image::createSampler(); Image::CreateSampler();
transitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); TransitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
std::vector<Vertex> vertexData = { std::vector<Vertex> vertex_data = {
{{0, 0}, {1.f, 1.f, 1.f, 1.f}, {0.0f, 0.0f}}, {{0, 0}, {1.f, 1.f, 1.f, 1.f}, {0.0f, 0.0f}},
{{width, 0}, {1.f, 1.f, 1.f, 1.f}, {1.0f, 0.0f}}, {{width, 0}, {1.f, 1.f, 1.f, 1.f}, {1.0f, 0.0f}},
{{width, height}, {1.f, 1.f, 1.f, 1.f}, {1.0f, 1.0f}}, {{width, height}, {1.f, 1.f, 1.f, 1.f}, {1.0f, 1.0f}},
{{0, height}, {1.f, 1.f, 1.f, 1.f}, {0.0f, 1.0f}} {{0, height}, {1.f, 1.f, 1.f, 1.f}, {0.0f, 1.0f}}
}; };
std::vector<std::uint16_t> indexData = { 0, 1, 2, 2, 3, 0 }; std::vector<std::uint16_t> index_data = { 0, 1, 2, 2, 3, 0 };
#ifdef DEBUG #ifdef DEBUG
_vbo.create(sizeof(Vertex) * vertexData.size(), vertexData.data(), name); m_vbo.Create(sizeof(Vertex) * vertex_data.size(), vertex_data.data(), name);
_ibo.create(sizeof(std::uint16_t) * indexData.size(), indexData.data(), name); m_ibo.Create(sizeof(std::uint16_t) * index_data.size(), index_data.data(), name);
_name = name; m_name = name;
#else #else
_vbo.create(sizeof(Vertex) * vertexData.size(), vertexData.data(), nullptr); m_vbo.Create(sizeof(Vertex) * vertex_data.size(), vertex_data.data(), nullptr);
_ibo.create(sizeof(std::uint16_t) * indexData.size(), indexData.data(), nullptr); m_ibo.Create(sizeof(std::uint16_t) * index_data.size(), index_data.data(), nullptr);
#endif #endif
Buffer staging_buffer; Buffer staging_buffer;
@@ -58,43 +58,43 @@ namespace mlx
if(pixels != nullptr) if(pixels != nullptr)
{ {
#ifdef DEBUG #ifdef DEBUG
staging_buffer.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, name, pixels); staging_buffer.Create(BufferType::HighDynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, name, pixels);
#else #else
staging_buffer.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, nullptr, pixels); staging_buffer.Create(BufferType::HighDynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, nullptr, pixels);
#endif #endif
} }
else else
{ {
std::vector<std::uint32_t> default_pixels(width * height, 0x00000000); std::vector<std::uint32_t> default_pixels(width * height, 0x00000000);
#ifdef DEBUG #ifdef DEBUG
staging_buffer.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, name, default_pixels.data()); staging_buffer.Create(BufferType::HighDynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, name, default_pixels.data());
#else #else
staging_buffer.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, nullptr, default_pixels.data()); staging_buffer.Create(BufferType::HighDynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, nullptr, default_pixels.data());
#endif #endif
} }
Image::copyFromBuffer(staging_buffer); Image::CopyFromBuffer(staging_buffer);
staging_buffer.destroy(); staging_buffer.Destroy();
} }
void Texture::setPixel(int x, int y, std::uint32_t color) noexcept void Texture::SetPixel(int x, int y, std::uint32_t color) noexcept
{ {
MLX_PROFILE_FUNCTION(); MLX_PROFILE_FUNCTION();
if(x < 0 || y < 0 || static_cast<std::uint32_t>(x) > getWidth() || static_cast<std::uint32_t>(y) > getHeight()) if(x < 0 || y < 0 || static_cast<std::uint32_t>(x) > GetWidth() || static_cast<std::uint32_t>(y) > GetHeight())
return; return;
if(_map == nullptr) if(m_map == nullptr)
openCPUmap(); PpenCPUmap();
_cpu_map[(y * getWidth()) + x] = color; m_cpu_map[(y * GetWidth()) + x] = color;
_has_been_modified = true; m_has_been_modified = true;
} }
int Texture::getPixel(int x, int y) noexcept int Texture::GetPixel(int x, int y) noexcept
{ {
MLX_PROFILE_FUNCTION(); MLX_PROFILE_FUNCTION();
if(x < 0 || y < 0 || static_cast<std::uint32_t>(x) > getWidth() || static_cast<std::uint32_t>(y) > getHeight()) if(x < 0 || y < 0 || static_cast<std::uint32_t>(x) > GetWidth() || static_cast<std::uint32_t>(y) > GetHeight())
return 0; return 0;
if(_map == nullptr) if(m_map == nullptr)
openCPUmap(); OpenCPUmap();
std::uint32_t color = _cpu_map[(y * getWidth()) + x]; std::uint32_t color = m_cpu_map[(y * GetWidth()) + x];
std::uint8_t* bytes = reinterpret_cast<std::uint8_t*>(&color); std::uint8_t* bytes = reinterpret_cast<std::uint8_t*>(&color);
std::uint8_t tmp = bytes[0]; std::uint8_t tmp = bytes[0];
bytes[0] = bytes[2]; bytes[0] = bytes[2];
@@ -102,86 +102,87 @@ namespace mlx
return *reinterpret_cast<int*>(bytes); return *reinterpret_cast<int*>(bytes);
} }
void Texture::openCPUmap() void Texture::OpenCPUmap()
{ {
MLX_PROFILE_FUNCTION(); MLX_PROFILE_FUNCTION();
if(_map != nullptr) if(m_map != nullptr)
return; return;
DebugLog("Texture : enabling CPU mapping");
std::size_t size = GetWidth() * GetHeight() * FormatSize(GetFormat());
m_buf_map.emplace();
#ifdef DEBUG #ifdef DEBUG
core::error::report(e_kind::message, "Texture : enabling CPU mapping"); m_buf_map->Create(BufferType::HighDynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, m_name.c_str());
#endif
std::size_t size = getWidth() * getHeight() * formatSize(getFormat());
_buf_map.emplace();
#ifdef DEBUG
_buf_map->create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, _name.c_str());
#else #else
_buf_map->create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, nullptr); m_buf_map->Create(BufferType::HighDynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, nullptr);
#endif
Image::copyToBuffer(*_buf_map);
_buf_map->mapMem(&_map);
_cpu_map = std::vector<std::uint32_t>(getWidth() * getHeight(), 0);
std::memcpy(_cpu_map.data(), _map, size);
#ifdef DEBUG
core::error::report(e_kind::message, "Texture : mapped CPU memory using staging buffer");
#endif #endif
Image::CopyToBuffer(*m_buf_map);
m_buf_map->MapMem(&_map);
m_cpu_map = std::vector<std::uint32_t>(GetWidth() * GetHeight(), 0);
std::memcpy(m_cpu_map.data(), m_map, size);
DebugLog("Texture : mapped CPU memory using staging buffer");
} }
void Texture::render(std::array<VkDescriptorSet, 2>& sets, Renderer& renderer, int x, int y) void Texture::Render(Renderer& renderer, int x, int y)
{ {
MLX_PROFILE_FUNCTION(); MLX_PROFILE_FUNCTION();
if(_has_been_modified) if(m_has_been_modified)
{ {
std::memcpy(_map, _cpu_map.data(), _cpu_map.size() * formatSize(getFormat())); std::memcpy(m_map, m_cpu_map.data(), m_cpu_map.size() * FormatSize(GetFormat()));
Image::copyFromBuffer(*_buf_map); Image::copyFromBuffer(*m_buf_map);
_has_been_modified = false; m_has_been_modified = false;
} }
if(!_set.isInit()) if(!m_set.IsInit())
_set = renderer.getFragDescriptorSet().duplicate(); m_set = renderer.GetFragDescriptorSet().Duplicate();
if(getLayout() != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) if(GetLayout() != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
transitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); TransitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
if(!_has_set_been_updated) if(!m_has_set_been_updated)
updateSet(0); UpdateSet(0);
auto cmd = renderer.getActiveCmdBuffer(); auto cmd = renderer.GetActiveCmdBuffer();
_vbo.bind(renderer); m_vbo.bind(renderer);
_ibo.bind(renderer); m_ibo.bind(renderer);
glm::vec2 translate(x, y); glm::vec2 translate(x, y);
vkCmdPushConstants(cmd.get(), renderer.getPipeline().getPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(translate), &translate); vkCmdPushConstants(cmd.Get(), renderer.GetPipeline().GetPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(translate), &translate);
sets[1] = _set.get(); m_set.Bind();
vkCmdBindDescriptorSets(renderer.getActiveCmdBuffer().get(), VK_PIPELINE_BIND_POINT_GRAPHICS, renderer.getPipeline().getPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr); vkCmdDrawIndexed(cmd.Get(), static_cast<std::uint32_t>(m_ibo.GetSize() / sizeof(std::uint16_t)), 1, 0, 0, 0);
vkCmdDrawIndexed(cmd.get(), static_cast<std::uint32_t>(_ibo.getSize() / sizeof(std::uint16_t)), 1, 0, 0, 0);
} }
void Texture::destroy() noexcept void Texture::Destroy() noexcept
{ {
MLX_PROFILE_FUNCTION(); MLX_PROFILE_FUNCTION();
Image::destroy(); Image::Destroy();
_set.destroy(); m_set.Destroy();
if(_buf_map.has_value()) if(m_buf_map.has_value())
_buf_map->destroy(); m_buf_map->Destroy();
_vbo.destroy(); m_vbo.destroy();
_ibo.destroy(); m_ibo.destroy();
} }
Texture stbTextureLoad(std::filesystem::path file, int* w, int* h) Texture stbTextureLoad(std::filesystem::path file, int* w, int* h)
{ {
MLX_PROFILE_FUNCTION(); MLX_PROFILE_FUNCTION();
Texture texture; Texture* texture = new Texture;
int channels; int channels;
std::uint8_t* data = nullptr; std::uint8_t* data = nullptr;
std::string filename = file.string(); std::string filename = file.string();
if(!std::filesystem::exists(std::move(file))) if(!std::filesystem::exists(std::move(file)))
core::error::report(e_kind::fatal_error, "Image : file not found '%s'", filename.c_str()); {
Error("Image : file not found '%s'", filename.c_str());
return nullptr;
}
if(stbi_is_hdr(filename.c_str())) if(stbi_is_hdr(filename.c_str()))
core::error::report(e_kind::fatal_error, "Texture : unsupported image format '%s'", filename.c_str()); {
Error("Texture : unsupported image format '%s'", filename.c_str());
return nullptr;
}
int dummy_w; int dummy_w;
int dummy_h; int dummy_h;
data = stbi_load(filename.c_str(), (w == nullptr ? &dummy_w : w), (h == nullptr ? &dummy_h : h), &channels, 4); data = stbi_load(filename.c_str(), (w == nullptr ? &dummy_w : w), (h == nullptr ? &dummy_h : h), &channels, 4);
#ifdef DEBUG #ifdef DEBUG
texture.create(data, (w == nullptr ? dummy_w : *w), (h == nullptr ? dummy_h : *h), VK_FORMAT_R8G8B8A8_UNORM, filename.c_str()); texture->Create(data, (w == nullptr ? dummy_w : *w), (h == nullptr ? dummy_h : *h), VK_FORMAT_R8G8B8A8_UNORM, filename.c_str());
#else #else
texture.create(data, (w == nullptr ? dummy_w : *w), (h == nullptr ? dummy_h : *h), VK_FORMAT_R8G8B8A8_UNORM, nullptr); texture->Create(data, (w == nullptr ? dummy_w : *w), (h == nullptr ? dummy_h : *h), VK_FORMAT_R8G8B8A8_UNORM, nullptr);
#endif #endif
stbi_image_free(data); stbi_image_free(data);
return texture; return texture;

View File

@@ -1,18 +1,18 @@
/* ************************************************************************** */ /* ************************************************************************** */
/* */ /* */
/* ::: :::::::: */ /* ::: :::::::: */
/* texture_atlas.cpp :+: :+: :+: */ /* TextureAtlas.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/07 16:40:09 by maldavid #+# #+# */ /* Created: 2023/04/07 16:40:09 by maldavid #+# #+# */
/* Updated: 2024/03/25 19:03:13 by maldavid ### ########.fr */ /* Updated: 2024/04/23 21:54:05 by maldavid ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include <pre_compiled.h> #include <PreCompiled.h>
#include <renderer/images/texture_atlas.h> #include <Renderer/Images/TextureAtlas.h>
#ifdef IMAGE_OPTIMIZED #ifdef IMAGE_OPTIMIZED
#define TILING VK_IMAGE_TILING_OPTIMAL #define TILING VK_IMAGE_TILING_OPTIMAL
@@ -22,37 +22,37 @@
namespace mlx namespace mlx
{ {
void TextureAtlas::create(std::uint8_t* pixels, std::uint32_t width, std::uint32_t height, VkFormat format, const char* name, bool dedicated_memory) void TextureAtlas::Create(std::uint8_t* pixels, std::uint32_t width, std::uint32_t height, VkFormat format, const char* name, bool dedicated_memory)
{ {
Image::create(width, height, format, TILING, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, name, dedicated_memory); Image::Create(width, height, format, TILING, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, name, dedicated_memory);
Image::createImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT); Image::CreateImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT);
Image::createSampler(); Image::CreateSampler();
transitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); TransitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
if(pixels == nullptr) if(pixels == nullptr)
{ {
core::error::report(e_kind::warning, "Renderer : creating an empty texture atlas. They cannot be updated after creation, this might be a mistake or a bug, please report"); Warning("Renderer : creating an empty texture atlas. They cannot be updated after creation, this might be a mistake or a bug, please report");
return; return;
} }
Buffer staging_buffer; Buffer staging_buffer;
std::size_t size = width * height * formatSize(format); std::size_t size = width * height * FormatSize(format);
staging_buffer.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, name, pixels); staging_buffer.Create(BufferType::HighDynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, name, pixels);
Image::copyFromBuffer(staging_buffer); Image::CopyFromBuffer(staging_buffer);
staging_buffer.destroy(); staging_buffer.Destroy();
} }
void TextureAtlas::render(Renderer& renderer, int x, int y, std::uint32_t ibo_size) const void TextureAtlas::Render(Renderer& renderer, int x, int y, std::uint32_t ibo_size) const
{ {
auto cmd = renderer.getActiveCmdBuffer().get(); auto cmd = renderer.GetActiveCmdBuffer().Get();
glm::vec2 translate(x, y); glm::vec2 translate(x, y);
vkCmdPushConstants(cmd, renderer.getPipeline().getPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(translate), &translate); vkCmdPushConstants(cmd, renderer.GetPipeline().GetPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(translate), &translate);
vkCmdDrawIndexed(cmd, ibo_size / sizeof(std::uint16_t), 1, 0, 0, 0); vkCmdDrawIndexed(cmd, ibo_size / sizeof(std::uint16_t), 1, 0, 0, 0);
} }
void TextureAtlas::destroy() noexcept void TextureAtlas::Destroy() noexcept
{ {
Image::destroy(); Image::Destroy();
_set.destroy(); m_set.Destroy();
} }
} }

View File

@@ -1,21 +1,21 @@
/* ************************************************************************** */ /* ************************************************************************** */
/* */ /* */
/* ::: :::::::: */ /* ::: :::::::: */
/* pipeline.cpp :+: :+: :+: */ /* Pipeline.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2022/12/18 21:27:38 by maldavid #+# #+# */ /* Created: 2022/12/18 21:27:38 by maldavid #+# #+# */
/* Updated: 2024/03/25 19:03:31 by maldavid ### ########.fr */ /* Updated: 2024/04/23 22:24:13 by maldavid ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include <pre_compiled.h> #include <PreCompiled.h>
#include "pipeline.h" #include <Renderer/Pipelines/Pipeline.h>
#include <renderer/renderer.h> #include <Renderer/Renderer.h>
#include <renderer/core/render_core.h> #include <Renderer/Core/RenderCore.h>
#include <renderer/descriptors/vk_descriptor_set_layout.h> #include <Renderer/Descriptors/DescriptorSetLayout.h>
namespace mlx namespace mlx
{ {
@@ -26,19 +26,23 @@ namespace mlx
layout(location = 1) in vec4 aColor; layout(location = 1) in vec4 aColor;
layout(location = 2) in vec2 aUV; layout(location = 2) in vec2 aUV;
layout(set = 0, binding = 0) uniform uProjection { layout(set = 0, binding = 0) uniform uProjection
{
mat4 mat; mat4 mat;
} uProj; } uProj;
layout(push_constant) uniform uModelPushConstant { layout(push_constant) uniform uModelPushConstant
{
vec2 vec; vec2 vec;
} uTranslate; } uTranslate;
out gl_PerVertex { out gl_PerVertex
{
vec4 gl_Position; vec4 gl_Position;
}; };
layout(location = 0) out struct { layout(location = 0) out struct
{
vec4 Color; vec4 Color;
vec2 UV; vec2 UV;
} Out; } Out;
@@ -113,7 +117,8 @@ namespace mlx
layout(set = 1, binding = 0) uniform sampler2D sTexture; layout(set = 1, binding = 0) uniform sampler2D sTexture;
layout(location = 0) in struct { layout(location = 0) in struct
{
vec4 Color; vec4 Color;
vec2 UV; vec2 UV;
} In; } In;
@@ -162,83 +167,83 @@ namespace mlx
0x000100fd,0x00010038 0x000100fd,0x00010038
}; };
void GraphicPipeline::init(Renderer& renderer) void GraphicPipeline::Init(Renderer& renderer)
{ {
VkShaderModuleCreateInfo createInfo{}; VkShaderModuleCreateInfo create_info{};
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
createInfo.codeSize = vertex_shader.size() * sizeof(std::uint32_t); create_info.codeSize = vertex_shader.size() * sizeof(std::uint32_t);
createInfo.pCode = vertex_shader.data(); create_info.pCode = vertex_shader.data();
VkShaderModule vshader; VkShaderModule vshader;
if(vkCreateShaderModule(Render_Core::get().getDevice().get(), &createInfo, nullptr, &vshader) != VK_SUCCESS) if(vkCreateShaderModule(RenderCore::Get().GetDevice().Get(), &create_info, nullptr, &vshader) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a vertex shader module"); FatalError("Vulkan : failed to create a vertex shader module");
VkPushConstantRange push_constant; VkPushConstantRange push_constant;
push_constant.offset = 0; push_constant.offset = 0;
push_constant.size = sizeof(glm::vec2); push_constant.size = sizeof(glm::vec2);
push_constant.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; push_constant.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
createInfo.codeSize = fragment_shader.size() * sizeof(std::uint32_t); create_info.codeSize = fragment_shader.size() * sizeof(std::uint32_t);
createInfo.pCode = fragment_shader.data(); create_info.pCode = fragment_shader.data();
VkShaderModule fshader; VkShaderModule fshader;
if(vkCreateShaderModule(Render_Core::get().getDevice().get(), &createInfo, nullptr, &fshader) != VK_SUCCESS) if(vkCreateShaderModule(RenderCore::Get().GetDevice().Get(), &create_info, nullptr, &fshader) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a fragment shader module"); FatalError("Vulkan : failed to create a fragment shader module");
VkPipelineShaderStageCreateInfo vertShaderStageInfo{}; VkPipelineShaderStageCreateInfo vert_shader_stage_info{};
vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; vert_shader_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; vert_shader_stage_info.stage = VK_SHADER_STAGE_VERTEX_BIT;
vertShaderStageInfo.module = vshader; vert_shader_stage_info.module = vshader;
vertShaderStageInfo.pName = "main"; vert_shader_stage_info.pName = "main";
VkPipelineShaderStageCreateInfo fragShaderStageInfo{}; VkPipelineShaderStageCreateInfo frag_shader_stage_info{};
fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; frag_shader_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT; frag_shader_stage_info.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
fragShaderStageInfo.module = fshader; frag_shader_stage_info.module = fshader;
fragShaderStageInfo.pName = "main"; frag_shader_stage_info.pName = "main";
std::array<VkPipelineShaderStageCreateInfo, 2> stages = {vertShaderStageInfo, fragShaderStageInfo}; std::array<VkPipelineShaderStageCreateInfo, 2> stages = { vert_shader_stage_info, frag_shader_stage_info };
auto bindingDescription = Vertex::getBindingDescription(); auto binding_description = Vertex::GetBindingDescription();
auto attributeDescriptions = Vertex::getAttributeDescriptions(); auto attribute_descriptions = Vertex::GetAttributeDescriptions();
VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo{}; VkPipelineVertexInputStateCreateInfo vertex_input_state_create_info{};
vertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; vertex_input_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertexInputStateCreateInfo.vertexBindingDescriptionCount = 1; vertex_input_state_create_info.vertexBindingDescriptionCount = 1;
vertexInputStateCreateInfo.pVertexBindingDescriptions = &bindingDescription; vertex_input_state_create_info.pVertexBindingDescriptions = &binding_description;
vertexInputStateCreateInfo.vertexAttributeDescriptionCount = static_cast<std::uint32_t>(attributeDescriptions.size()); vertex_input_state_create_info.vertexAttributeDescriptionCount = static_cast<std::uint32_t>(attribute_descriptions.size());
vertexInputStateCreateInfo.pVertexAttributeDescriptions = attributeDescriptions.data(); vertex_input_state_create_info.pVertexAttributeDescriptions = attribute_descriptions.data();
VkPipelineInputAssemblyStateCreateInfo inputAssembly{}; VkPipelineInputAssemblyStateCreateInfo input_assembly{};
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; input_assembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; input_assembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
inputAssembly.primitiveRestartEnable = VK_FALSE; input_assembly.primitiveRestartEnable = VK_FALSE;
VkDynamicState states[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; VkDynamicState states[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
constexpr std::size_t statesCount = sizeof(states) / sizeof(VkDynamicState); constexpr std::size_t states_count = sizeof(states) / sizeof(VkDynamicState);
VkPipelineDynamicStateCreateInfo dynamicStates{}; VkPipelineDynamicStateCreateInfo dynamic_states{};
dynamicStates.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; dynamic_states.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
dynamicStates.dynamicStateCount = statesCount; dynamic_states.dynamicStateCount = states_count;
dynamicStates.pDynamicStates = states; dynamic_states.pDynamicStates = states;
VkViewport viewport{}; VkViewport viewport{};
viewport.x = 0.0f; viewport.x = 0.0f;
viewport.y = 0.0f; viewport.y = 0.0f;
viewport.width = (float)renderer.getFrameBuffer(0).getWidth(); viewport.width = (float)renderer.GetFrameBuffer(0).GetWidth();
viewport.height = (float)renderer.getFrameBuffer(0).getHeight(); viewport.height = (float)renderer.GetFrameBuffer(0).GetHeight();
viewport.minDepth = 0.0f; viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f; viewport.maxDepth = 1.0f;
VkRect2D scissor{}; VkRect2D scissor{};
scissor.offset = { 0, 0 }; scissor.offset = { 0, 0 };
scissor.extent = { renderer.getFrameBuffer(0).getWidth(), renderer.getFrameBuffer(0).getHeight()}; scissor.extent = { renderer.GetFrameBuffer(0).GetWidth(), renderer.GetFrameBuffer(0).GetHeight()};
VkPipelineViewportStateCreateInfo viewportState{}; VkPipelineViewportStateCreateInfo viewport_state{};
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
viewportState.viewportCount = 1; viewport_state.viewportCount = 1;
viewportState.pViewports = &viewport; viewport_state.pViewports = &viewport;
viewportState.scissorCount = 1; viewport_state.scissorCount = 1;
viewportState.pScissors = &scissor; viewport_state.pScissors = &scissor;
VkPipelineRasterizationStateCreateInfo rasterizer{}; VkPipelineRasterizationStateCreateInfo rasterizer{};
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
@@ -255,76 +260,72 @@ namespace mlx
multisampling.sampleShadingEnable = VK_FALSE; multisampling.sampleShadingEnable = VK_FALSE;
multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
VkPipelineColorBlendAttachmentState colorBlendAttachment{}; VkPipelineColorBlendAttachmentState color_blend_attachment{};
colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; color_blend_attachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
colorBlendAttachment.blendEnable = VK_TRUE; color_blend_attachment.blendEnable = VK_TRUE;
colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; color_blend_attachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; color_blend_attachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD; color_blend_attachment.colorBlendOp = VK_BLEND_OP_ADD;
colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; color_blend_attachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; color_blend_attachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD; color_blend_attachment.alphaBlendOp = VK_BLEND_OP_ADD;
VkPipelineColorBlendStateCreateInfo colorBlending{}; VkPipelineColorBlendStateCreateInfo color_blending{};
colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; color_blending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
colorBlending.logicOpEnable = VK_FALSE; color_blending.logicOpEnable = VK_FALSE;
colorBlending.logicOp = VK_LOGIC_OP_COPY; color_blending.logicOp = VK_LOGIC_OP_COPY;
colorBlending.attachmentCount = 1; color_blending.attachmentCount = 1;
colorBlending.pAttachments = &colorBlendAttachment; color_blending.pAttachments = &color_blend_attachment;
colorBlending.blendConstants[0] = 1.0f; color_blending.blendConstants[0] = 1.0f;
colorBlending.blendConstants[1] = 1.0f; color_blending.blendConstants[1] = 1.0f;
colorBlending.blendConstants[2] = 1.0f; color_blending.blendConstants[2] = 1.0f;
colorBlending.blendConstants[3] = 1.0f; color_blending.blendConstants[3] = 1.0f;
VkDescriptorSetLayout layouts[] = { VkDescriptorSetLayout layouts[] = {
renderer.getVertDescriptorSetLayout().get(), renderer.GetVertDescriptorSet().GetLayout(),
renderer.getFragDescriptorSetLayout().get() renderer.GetFragDescriptorSet().GetLayout()
}; };
VkPipelineLayoutCreateInfo pipelineLayoutInfo{}; VkPipelineLayoutCreateInfo pipeline_layout_info{};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.setLayoutCount = 2; pipeline_layout_info.setLayoutCount = 2;
pipelineLayoutInfo.pSetLayouts = layouts; pipeline_layout_info.pSetLayouts = layouts;
pipelineLayoutInfo.pushConstantRangeCount = 1; pipeline_layout_info.pushConstantRangeCount = 1;
pipelineLayoutInfo.pPushConstantRanges = &push_constant; pipeline_layout_info.pPushConstantRanges = &push_constant;
if(vkCreatePipelineLayout(Render_Core::get().getDevice().get(), &pipelineLayoutInfo, nullptr, &_pipeline_layout) != VK_SUCCESS) if(vkCreatePipelineLayout(RenderCore::Get().GetDevice().Get(), &pipeline_layout_info, nullptr, &m_pipeline_layout) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a graphics pipeline layout"); FatalError("Vulkan : failed to create a graphics pipeline layout");
VkGraphicsPipelineCreateInfo pipelineInfo{}; VkGraphicsPipelineCreateInfo pipeline_info{};
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
pipelineInfo.stageCount = stages.size(); pipeline_info.stageCount = stages.size();
pipelineInfo.pStages = stages.data(); pipeline_info.pStages = stages.data();
pipelineInfo.pVertexInputState = &vertexInputStateCreateInfo; pipeline_info.pVertexInputState = &vertex_input_state_create_info;
pipelineInfo.pInputAssemblyState = &inputAssembly; pipeline_info.pInputAssemblyState = &input_assembly;
pipelineInfo.pViewportState = &viewportState; pipeline_info.pViewportState = &viewport_state;
pipelineInfo.pRasterizationState = &rasterizer; pipeline_info.pRasterizationState = &rasterizer;
pipelineInfo.pMultisampleState = &multisampling; pipeline_info.pMultisampleState = &multisampling;
pipelineInfo.pColorBlendState = &colorBlending; pipeline_info.pColorBlendState = &color_blending;
pipelineInfo.pDynamicState = &dynamicStates; pipeline_info.pDynamicState = &dynamic_states;
pipelineInfo.layout = _pipeline_layout; pipeline_info.layout = m_pipeline_layout;
pipelineInfo.renderPass = renderer.getRenderPass().get(); pipeline_info.renderPass = renderer.GetRenderPass().Get();
pipelineInfo.subpass = 0; pipeline_info.subpass = 0;
pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
VkResult res = vkCreateGraphicsPipelines(Render_Core::get().getDevice().get(), VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &_graphics_pipeline); VkResult res = vkCreateGraphicsPipelines(RenderCore::Get().GetDevice().Get(), VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &m_graphics_pipeline);
if(res != VK_SUCCESS) if(res != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a graphics pipeline, %s", RCore::verbaliseResultVk(res)); FatalError("Vulkan : failed to create a graphics pipeline, %", VerbaliseVkResult(res));
#ifdef DEBUG DebugLog("Vulkan : created new graphic pipeline");
core::error::report(e_kind::message, "Vulkan : created new graphic pipeline");
#endif
vkDestroyShaderModule(Render_Core::get().getDevice().get(), fshader, nullptr); vkDestroyShaderModule(RenderCore::Get().GetDevice().Get(), fshader, nullptr);
vkDestroyShaderModule(Render_Core::get().getDevice().get(), vshader, nullptr); vkDestroyShaderModule(RenderCore::Get().GetDevice().Get(), vshader, nullptr);
} }
void GraphicPipeline::destroy() noexcept void GraphicPipeline::Destroy() noexcept
{ {
vkDestroyPipeline(Render_Core::get().getDevice().get(), _graphics_pipeline, nullptr); vkDestroyPipeline(RenderCore::Get().GetDevice().Get(), m_graphics_pipeline, nullptr);
vkDestroyPipelineLayout(Render_Core::get().getDevice().get(), _pipeline_layout, nullptr); vkDestroyPipelineLayout(RenderCore::Get().GetDevice().Get(), m_pipeline_layout, nullptr);
_graphics_pipeline = VK_NULL_HANDLE; m_graphics_pipeline = VK_NULL_HANDLE;
#ifdef DEBUG DebugLog("Vulkan : destroyed a graphics pipeline");
core::error::report(e_kind::message, "Vulkan : destroyed a graphics pipeline");
#endif
} }
} }

View File

@@ -1,53 +1,49 @@
/* ************************************************************************** */ /* ************************************************************************** */
/* */ /* */
/* ::: :::::::: */ /* ::: :::::::: */
/* vk_framebuffer.cpp :+: :+: :+: */ /* Framebuffer.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:18:06 by maldavid #+# #+# */ /* Created: 2022/10/06 18:18:06 by maldavid #+# #+# */
/* Updated: 2024/03/25 19:03:35 by maldavid ### ########.fr */ /* Updated: 2024/04/23 22:28:07 by maldavid ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include <pre_compiled.h> #include <PreCompiled.h>
#include <renderer/core/render_core.h> #include <Renderer/Core/RenderCore.h>
#include <renderer/renderer.h> #include <Renderer/Renderer.h>
#include <renderer/images/vk_image.h> #include <Renderer/Images/Image.h>
namespace mlx namespace mlx
{ {
void FrameBuffer::init(RenderPass& renderpass, Image& image) void FrameBuffer::Init(RenderPass& renderpass, Image& image)
{ {
VkImageView attachments[] = { image.getImageView() }; VkImageView attachments[] = { image.GetImageView() };
_width = image.getWidth(); m_width = image.GetWidth();
_height = image.getHeight(); m_height = image.GetHeight();
VkFramebufferCreateInfo framebufferInfo{}; VkFramebufferCreateInfo framebuffer_info{};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferInfo.renderPass = renderpass.get(); framebuffer_info.renderPass = renderpass.get();
framebufferInfo.attachmentCount = 1; framebuffer_info.attachmentCount = 1;
framebufferInfo.pAttachments = attachments; framebuffer_info.pAttachments = attachments;
framebufferInfo.width = _width; framebuffer_info.width = _width;
framebufferInfo.height = _height; framebuffer_info.height = _height;
framebufferInfo.layers = 1; framebuffer_info.layers = 1;
VkResult res = vkCreateFramebuffer(Render_Core::get().getDevice().get(), &framebufferInfo, nullptr, &_framebuffer); VkResult res = vkCreateFramebuffer(RenderCore::Get().GetDevice().Get(), &framebuffer_info, nullptr, &m_framebuffer);
if(res != VK_SUCCESS) if(res != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a framebuffer, %s", RCore::verbaliseResultVk(res)); FatalError("Vulkan : failed to create a framebuffer, %s", RCore::verbaliseResultVk(res));
#ifdef DEBUG DebugLog("Vulkan : created new framebuffer");
core::error::report(e_kind::message, "Vulkan : created new framebuffer");
#endif
} }
void FrameBuffer::destroy() noexcept void FrameBuffer::Destroy() noexcept
{ {
vkDestroyFramebuffer(Render_Core::get().getDevice().get(), _framebuffer, nullptr); vkDestroyFramebuffer(RenderCore::Get().GetDevice().Get(), m_framebuffer, nullptr);
_framebuffer = VK_NULL_HANDLE; m_framebuffer = VK_NULL_HANDLE;
#ifdef DEBUG DebugLog("Vulkan : destroyed a framebuffer");
core::error::report(e_kind::message, "Vulkan : destroyed a framebuffer");
#endif
} }
} }

View File

@@ -1,12 +1,12 @@
/* ************************************************************************** */ /* ************************************************************************** */
/* */ /* */
/* ::: :::::::: */ /* ::: :::::::: */
/* vk_render_pass.cpp :+: :+: :+: */ /* Renderpass.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:21:36 by maldavid #+# #+# */ /* Created: 2022/10/06 18:21:36 by maldavid #+# #+# */
/* Updated: 2024/03/25 19:03:37 by maldavid ### ########.fr */ /* Updated: 2024/04/23 22:31:09 by maldavid ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -20,21 +20,21 @@
namespace mlx namespace mlx
{ {
static const VkClearValue clearColor = {{{ 0.f, 0.f, 0.f, 1.0f }}}; // wtf, this mess to satisfy a warning static const VkClearValue clear_color = {{{ 0.f, 0.f, 0.f, 1.0f }}}; // wtf, this mess to satisfy a warning
void RenderPass::init(VkFormat attachement_format, VkImageLayout layout) void RenderPass::Init(VkFormat attachement_format, VkImageLayout layout)
{ {
VkAttachmentDescription colorAttachment{}; VkAttachmentDescription color_attachment{};
colorAttachment.format = attachement_format; color_attachment.format = attachement_format;
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT; color_attachment.samples = VK_SAMPLE_COUNT_1_BIT;
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; color_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; color_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; color_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
colorAttachment.finalLayout = layout; color_attachment.finalLayout = layout;
VkAttachmentReference colorAttachmentRef{}; VkAttachmentReference color_attachment_ref{};
colorAttachmentRef.attachment = 0; colorAttachmentRef.attachment = 0;
colorAttachmentRef.layout = (layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : layout); colorAttachmentRef.layout = (layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : layout);
@@ -45,77 +45,73 @@ namespace mlx
VkSubpassDescription subpasses[] = { subpass1 }; VkSubpassDescription subpasses[] = { subpass1 };
std::vector<VkSubpassDependency> subpassesDeps; std::vector<VkSubpassDependency> subpasses_deps;
subpassesDeps.emplace_back(); subpasses_deps.emplace_back();
subpassesDeps.back().srcSubpass = VK_SUBPASS_EXTERNAL; subpasses_deps.back().srcSubpass = VK_SUBPASS_EXTERNAL;
subpassesDeps.back().dstSubpass = 0; subpasses_deps.back().dstSubpass = 0;
subpassesDeps.back().srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; subpasses_deps.back().srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
subpassesDeps.back().dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; subpasses_deps.back().dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
subpassesDeps.back().srcAccessMask = VK_ACCESS_MEMORY_READ_BIT; subpasses_deps.back().srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
subpassesDeps.back().dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; subpasses_deps.back().dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
subpassesDeps.back().dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; subpasses_deps.back().dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
subpassesDeps.emplace_back(); subpasses_deps.emplace_back();
subpassesDeps.back().srcSubpass = 0; subpasses_deps.back().srcSubpass = 0;
subpassesDeps.back().dstSubpass = VK_SUBPASS_EXTERNAL; subpasses_deps.back().dstSubpass = VK_SUBPASS_EXTERNAL;
subpassesDeps.back().srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; subpasses_deps.back().srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
subpassesDeps.back().dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; subpasses_deps.back().dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
subpassesDeps.back().srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; subpasses_deps.back().srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
subpassesDeps.back().dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; subpasses_deps.back().dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
subpassesDeps.back().dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; subpasses_deps.back().dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
VkRenderPassCreateInfo renderPassInfo{}; VkRenderPassCreateInfo render_pass_info{};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassInfo.attachmentCount = 1; render_pass_info.attachmentCount = 1;
renderPassInfo.pAttachments = &colorAttachment; render_pass_info.pAttachments = &color_attachment;
renderPassInfo.subpassCount = sizeof(subpasses) / sizeof(VkSubpassDescription); render_pass_info.subpassCount = sizeof(subpasses) / sizeof(VkSubpassDescription);
renderPassInfo.pSubpasses = subpasses; render_pass_info.pSubpasses = subpasses;
renderPassInfo.dependencyCount = static_cast<std::uint32_t>(subpassesDeps.size()); render_pass_info.dependencyCount = static_cast<std::uint32_t>(subpasses_deps.size());
renderPassInfo.pDependencies = subpassesDeps.data(); render_pass_info.pDependencies = subpasses_deps.data();
VkResult res = vkCreateRenderPass(Render_Core::get().getDevice().get(), &renderPassInfo, nullptr, &_render_pass); VkResult res = vkCreateRenderPass(RenderCore::Get().GetDevice().Get(), &render_pass_info, nullptr, &m_render_pass);
if(res != VK_SUCCESS) if(res != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create render pass, %s", RCore::verbaliseResultVk(res)); FatalError("Vulkan : failed to create render pass, %", VerbaliseVkResult(res));
#ifdef DEBUG DebugLog("Vulkan : created new render pass");
core::error::report(e_kind::message, "Vulkan : created new render pass");
#endif
} }
void RenderPass::begin(class CmdBuffer& cmd, class FrameBuffer& fb) void RenderPass::Begin(class CommandBuffer& cmd, class FrameBuffer& fb)
{ {
MLX_PROFILE_FUNCTION(); MLX_PROFILE_FUNCTION();
if(_is_running) if(m_is_running)
return; return;
VkRenderPassBeginInfo renderPassInfo{}; VkRenderPassBeginInfo render_pass_info{};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassInfo.renderPass = _render_pass; render_pass_info.renderPass = m_render_pass;
renderPassInfo.framebuffer = fb.get(); render_pass_info.framebuffer = fb.Get();
renderPassInfo.renderArea.offset = { 0, 0 }; render_pass_info.renderArea.offset = { 0, 0 };
renderPassInfo.renderArea.extent = { fb.getWidth(), fb.getHeight() }; render_pass_info.renderArea.extent = { fb.GetWidth(), fb.GetHeight() };
renderPassInfo.clearValueCount = 1; render_pass_info.clearValueCount = 1;
renderPassInfo.pClearValues = &clearColor; render_pass_info.pClearValues = &clear_color;
vkCmdBeginRenderPass(cmd.get(), &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); vkCmdBeginRenderPass(cmd.Get(), &render_pass_info, VK_SUBPASS_CONTENTS_INLINE);
_is_running = true; m_is_running = true;
} }
void RenderPass::end(class CmdBuffer& cmd) void RenderPass::End(class CommandBuffer& cmd)
{ {
MLX_PROFILE_FUNCTION(); MLX_PROFILE_FUNCTION();
if(!_is_running) if(!m_is_running)
return; return;
vkCmdEndRenderPass(cmd.get()); vkCmdEndRenderPass(cmdd.Get());
_is_running = false; m_is_running = false;
} }
void RenderPass::destroy() noexcept void RenderPass::Destroy() noexcept
{ {
vkDestroyRenderPass(Render_Core::get().getDevice().get(), _render_pass, nullptr); vkDestroyRenderPass(RenderCore::Get().GetDevice().Get(), m_render_pass, nullptr);
_render_pass = VK_NULL_HANDLE; m_render_pass = VK_NULL_HANDLE;
#ifdef DEBUG DebugLog("Vulkan : destroyed a renderpass");
core::error::report(e_kind::message, "Vulkan : destroyed a renderpass");
#endif
} }
} }

View File

@@ -1,152 +1,150 @@
/* ************************************************************************** */ /* ************************************************************************** */
/* */ /* */
/* ::: :::::::: */ /* ::: :::::::: */
/* vk_swapchain.cpp :+: :+: :+: */ /* Swapchain.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:22:28 by maldavid #+# #+# */ /* Created: 2022/10/06 18:22:28 by maldavid #+# #+# */
/* Updated: 2024/03/25 23:09:33 by maldavid ### ########.fr */ /* Updated: 2024/04/23 22:43:10 by maldavid ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include <pre_compiled.h> #include <PreCompiled.h>
#include <renderer/core/render_core.h> #include <Renderer/Core/RenderCore.h>
#include <renderer/renderer.h> #include <Renderer/Renderer.h>
#include <platform/window.h> #include <Platform/Window.h>
namespace mlx namespace mlx
{ {
void SwapChain::init(Renderer* renderer) void SwapChain::Init(NonOwningPtr<Renderer> renderer)
{ {
VkDevice device = Render_Core::get().getDevice().get(); VkDevice device = RenderCore::get().GetDevice().Get();
_renderer = renderer; m_renderer = renderer;
_swapchain_support = querySwapChainSupport(Render_Core::get().getDevice().getPhysicalDevice()); m_swapchain_support = QuerySwapChainSupport(RenderCore::Get().GetDevice().GetPhysicalDevice());
VkSurfaceFormatKHR surfaceFormat = renderer->getSurface().chooseSwapSurfaceFormat(_swapchain_support.formats); VkSurfaceFormatKHR surface_format = renderer->GetSurface().ChooseSwapSurfaceFormat(m_swapchain_support.formats);
VkPresentModeKHR presentMode = chooseSwapPresentMode(_swapchain_support.present_modes); VkPresentModeKHR present_mode = ChooseSwapPresentMode(m_swapchain_support.present_modes);
_extent = chooseSwapExtent(_swapchain_support.capabilities); m_extent = ChooseSwapExtent(m_swapchain_support.capabilities);
std::uint32_t imageCount = _swapchain_support.capabilities.minImageCount + 1; std::uint32_t image_count = m_swapchain_support.capabilities.minImageCount + 1;
if(_swapchain_support.capabilities.maxImageCount > 0 && imageCount > _swapchain_support.capabilities.maxImageCount) if(m_swapchain_support.capabilities.maxImageCount > 0 && image_count > m_swapchain_support.capabilities.maxImageCount)
imageCount = _swapchain_support.capabilities.maxImageCount; image_count = m_swapchain_support.capabilities.maxImageCount;
Queues::QueueFamilyIndices indices = Render_Core::get().getQueue().findQueueFamilies(Render_Core::get().getDevice().getPhysicalDevice()); Queues::QueueFamilyIndices indices = RenderCore::Get().GetQueue().FindQueueFamilies(RenderCore::Get().GetDevice().GetPhysicalDevice());
std::uint32_t queueFamilyIndices[] = { indices.graphics_family.value(), indices.present_family.value() }; std::uint32_t queue_family_indices[] = { indices.graphics_family.value(), indices.present_family.value() };
VkSwapchainCreateInfoKHR createInfo{}; VkSwapchainCreateInfoKHR create_info{};
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
createInfo.surface = renderer->getSurface().get(); create_info.surface = renderer->GetSurface().Get();
createInfo.minImageCount = imageCount; create_info.minImageCount = image_count;
createInfo.imageFormat = surfaceFormat.format; create_info.imageFormat = surface_format.format;
createInfo.imageColorSpace = surfaceFormat.colorSpace; create_info.imageColorSpace = surface_format.colorSpace;
createInfo.imageExtent = _extent; create_info.imageExtent = m_extent;
createInfo.imageArrayLayers = 1; create_info.imageArrayLayers = 1;
createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
createInfo.preTransform = _swapchain_support.capabilities.currentTransform; create_info.preTransform = m_swapchain_support.capabilities.currentTransform;
createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
createInfo.presentMode = presentMode; create_info.presentMode = present_mode;
createInfo.clipped = VK_TRUE; create_info.clipped = VK_TRUE;
createInfo.oldSwapchain = VK_NULL_HANDLE; create_info.oldSwapchain = VK_NULL_HANDLE;
if(indices.graphics_family != indices.present_family) if(indices.graphics_family != indices.present_family)
{ {
createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT; create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
createInfo.queueFamilyIndexCount = 2; create_info.queueFamilyIndexCount = 2;
createInfo.pQueueFamilyIndices = queueFamilyIndices; create_info.pQueueFamilyIndices = queue_family_indices;
} }
else else
createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
VkResult res = vkCreateSwapchainKHR(device, &createInfo, nullptr, &_swapchain); VkResult res = vkCreateSwapchainKHR(device, &create_info, nullptr, &m_swapchain);
if(res != VK_SUCCESS) if(res != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create the swapchain, %s", RCore::verbaliseResultVk(res)); FatalError("Vulkan : failed to create the swapchain, %", VerbaliseVkResult(res));
std::vector<VkImage> tmp; std::vector<VkImage> tmp;
vkGetSwapchainImagesKHR(device, _swapchain, &imageCount, nullptr); vkGetSwapchainImagesKHR(device, m_swapchain, &image_count, nullptr);
_images.resize(imageCount); m_images.resize(image_count);
tmp.resize(imageCount); tmp.resize(image_count);
vkGetSwapchainImagesKHR(device, _swapchain, &imageCount, tmp.data()); vkGetSwapchainImagesKHR(device, m_swapchain, &image_count, tmp.data());
for(std::size_t i = 0; i < imageCount; i++) for(std::size_t i = 0; i < image_count; i++)
{ {
_images[i].create(tmp[i], surfaceFormat.format, _extent.width, _extent.height); m_images[i].Create(tmp[i], surface_format.format, m_extent.width, m_extent.height);
_images[i].transitionLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); m_images[i].TransitionLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
_images[i].createImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT); m_images[i].CreateImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT);
} }
_swapchain_image_format = surfaceFormat.format; m_swapchain_image_format = surface_format.format;
#ifdef DEBUG DebugLog("Vulkan : created new swapchain");
core::error::report(e_kind::message, "Vulkan : created new swapchain");
#endif
} }
SwapChain::SwapChainSupportDetails SwapChain::querySwapChainSupport(VkPhysicalDevice device) SwapChain::SwapChainSupportDetails SwapChain::QuerySwapChainSupport(VkPhysicalDevice device)
{ {
SwapChain::SwapChainSupportDetails details; SwapChain::SwapChainSupportDetails details;
VkSurfaceKHR surface = _renderer->getSurface().get(); VkSurfaceKHR surface = m_renderer->GetSurface().Get();
if(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &details.capabilities) != VK_SUCCESS) if(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &details.capabilities) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : unable to retrieve surface capabilities"); FatalError("Vulkan : unable to retrieve surface capabilities");
std::uint32_t formatCount = 0; std::uint32_t format_count = 0;
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, nullptr); vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &format_count, nullptr);
if(formatCount != 0) if(format_count != 0)
{ {
details.formats.resize(formatCount); details.formats.resize(format_count);
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, details.formats.data()); vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &format_count, details.formats.data());
} }
std::uint32_t presentModeCount; std::uint32_t present_mode_count;
vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, nullptr); vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &present_mode_count, nullptr);
if(presentModeCount != 0) if(present_mode_count != 0)
{ {
details.present_modes.resize(presentModeCount); details.present_modes.resize(present_mode_count);
vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, details.present_modes.data()); vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &present_mode_count, details.present_modes.data());
} }
return details; return details;
} }
VkPresentModeKHR SwapChain::chooseSwapPresentMode([[maybe_unused]] const std::vector<VkPresentModeKHR>& availablePresentModes) VkPresentModeKHR SwapChain::chooseSwapPresentMode([[maybe_unused]] const std::vector<VkPresentModeKHR>& available_present_modes)
{ {
// in the future, you may choose to activate vsync or not // in the future, you may choose to activate vsync or not
return VK_PRESENT_MODE_IMMEDIATE_KHR; return VK_PRESENT_MODE_IMMEDIATE_KHR;
} }
VkExtent2D SwapChain::chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities) VkExtent2D SwapChain::ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities)
{ {
if(capabilities.currentExtent.width != std::numeric_limits<std::uint32_t>::max()) if(capabilities.currentExtent.width != std::numeric_limits<std::uint32_t>::max())
return capabilities.currentExtent; return capabilities.currentExtent;
int width, height; int width, height;
glfwGetFramebufferSize(_renderer->getWindow()->getNativeWindow(), &width, &height); glfwGetFramebufferSize(m_renderer->GetWindow()->GetNativeWindow(), &width, &height);
VkExtent2D actualExtent = { static_cast<std::uint32_t>(width), static_cast<std::uint32_t>(height) }; VkExtent2D actual_extent = { static_cast<std::uint32_t>(width), static_cast<std::uint32_t>(height) };
actualExtent.width = std::clamp(actualExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width); actual_extent.width = std::clamp(actual_extent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
actualExtent.height = std::clamp(actualExtent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height); actual_extent.height = std::clamp(actual_extent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
return actualExtent; return actual_extent;
} }
void SwapChain::recreate() void SwapChain::Recreate()
{ {
destroy(); Destroy();
init(_renderer); Init(m_renderer);
} }
void SwapChain::destroy() noexcept void SwapChain::Destroy() noexcept
{ {
if(_swapchain == VK_NULL_HANDLE) if(m_swapchain == VK_NULL_HANDLE)
return; return;
vkDeviceWaitIdle(Render_Core::get().getDevice().get()); vkDeviceWaitIdle(RenderCore::Get().GetDevice().Get());
vkDestroySwapchainKHR(Render_Core::get().getDevice().get(), _swapchain, nullptr); vkDestroySwapchainKHR(RenderCore::Get().GetDevice().Get(), m_swapchain, nullptr);
_swapchain = VK_NULL_HANDLE; m_swapchain = VK_NULL_HANDLE;
for(Image& img : _images) for(Image& img : m_images)
img.destroyImageView(); img.DestroyImageView();
} }
} }

View File

@@ -1,48 +1,47 @@
/* ************************************************************************** */ /* ************************************************************************** */
/* */ /* */
/* ::: :::::::: */ /* ::: :::::::: */
/* font.cpp :+: :+: :+: */ /* Font.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/12/11 22:06:09 by kbz_8 #+# #+# */ /* Created: 2023/12/11 22:06:09 by kbz_8 #+# #+# */
/* Updated: 2024/03/25 19:03:54 by maldavid ### ########.fr */ /* Updated: 2024/04/23 22:48:30 by maldavid ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include <pre_compiled.h> #include <PreCompiled.h>
#include <renderer/texts/font.h> #include <Renderer/Texts/Font.h>
#include <renderer/renderer.h> #include <Renderer/Renderer.h>
#include <core/profiler.h>
constexpr const int RANGE = 1024; constexpr const int RANGE = 1024;
namespace mlx namespace mlx
{ {
Font::Font(Renderer& renderer, const std::filesystem::path& path, float scale) : _name(path.string()), _renderer(renderer), _scale(scale) Font::Font(Renderer& renderer, const std::filesystem::path& path, float scale) : m_name(path.string()), m_renderer(renderer), m_scale(scale)
{ {
_build_data = path; m_build_data = path;
} }
Font::Font(class Renderer& renderer, const std::string& name, const std::vector<std::uint8_t>& ttf_data, float scale) : _name(name), _renderer(renderer), _scale(scale) Font::Font(class Renderer& renderer, const std::string& name, const std::vector<std::uint8_t>& ttf_data, float scale) : m_name(name), m_renderer(renderer), m_scale(scale)
{ {
_build_data = ttf_data; m_build_data = ttf_data;
} }
void Font::buildFont() void Font::BuildFont()
{ {
MLX_PROFILE_FUNCTION(); MLX_PROFILE_FUNCTION();
std::vector<std::uint8_t> file_bytes; std::vector<std::uint8_t> file_bytes;
if(std::holds_alternative<std::filesystem::path>(_build_data)) if(std::holds_alternative<std::filesystem::path>(m_build_data))
{ {
std::ifstream file(std::get<std::filesystem::path>(_build_data), std::ios::binary); std::ifstream file(std::get<std::filesystem::path>(m_build_data), std::ios::binary);
if(!file.is_open()) if(!file.is_open())
{ {
core::error::report(e_kind::error, "Font load : cannot open font file, %s", _name.c_str()); Error("Font load : cannot open font file, %", m_name.c_str());
return; return;
} }
std::ifstream::pos_type fileSize = std::filesystem::file_size(std::get<std::filesystem::path>(_build_data)); std::ifstream::pos_type fileSize = std::filesystem::file_size(std::get<std::filesystem::path>(m_build_data));
file.seekg(0, std::ios::beg); file.seekg(0, std::ios::beg);
file_bytes.resize(fileSize); file_bytes.resize(fileSize);
file.read(reinterpret_cast<char*>(file_bytes.data()), fileSize); file.read(reinterpret_cast<char*>(file_bytes.data()), fileSize);
@@ -53,10 +52,10 @@ namespace mlx
std::vector<std::uint8_t> vulkan_bitmap(RANGE * RANGE * 4); std::vector<std::uint8_t> vulkan_bitmap(RANGE * RANGE * 4);
stbtt_pack_context pc; stbtt_pack_context pc;
stbtt_PackBegin(&pc, tmp_bitmap.data(), RANGE, RANGE, RANGE, 1, nullptr); stbtt_PackBegin(&pc, tmp_bitmap.data(), RANGE, RANGE, RANGE, 1, nullptr);
if(std::holds_alternative<std::filesystem::path>(_build_data)) if(std::holds_alternative<std::filesystem::path>(m_build_data))
stbtt_PackFontRange(&pc, file_bytes.data(), 0, _scale, 32, 96, _cdata.data()); stbtt_PackFontRange(&pc, file_bytes.data(), 0, m_scale, 32, 96, m_cdata.data());
else else
stbtt_PackFontRange(&pc, std::get<std::vector<std::uint8_t>>(_build_data).data(), 0, _scale, 32, 96, _cdata.data()); stbtt_PackFontRange(&pc, std::get<std::vector<std::uint8_t>>(m_build_data).data(), 0, m_scale, 32, 96, m_cdata.data());
stbtt_PackEnd(&pc); stbtt_PackEnd(&pc);
for(int i = 0, j = 0; i < RANGE * RANGE; i++, j += 4) for(int i = 0, j = 0; i < RANGE * RANGE; i++, j += 4)
{ {
@@ -66,24 +65,24 @@ namespace mlx
vulkan_bitmap[j + 3] = tmp_bitmap[i]; vulkan_bitmap[j + 3] = tmp_bitmap[i];
} }
#ifdef DEBUG #ifdef DEBUG
_atlas.create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, std::string(_name + "_font_altas").c_str(), true); m_atlas.Create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, std::string(m_name + "_font_altas").c_str(), true);
#else #else
_atlas.create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, nullptr, true); m_atlas.Create(vulkan_bitmap.data(), RANGE, RANGE, VK_FORMAT_R8G8B8A8_UNORM, nullptr, true);
#endif #endif
_atlas.setDescriptor(_renderer.getFragDescriptorSet().duplicate()); m_atlas.SetDescriptor(m_renderer.GetFragDescriptorSet().Duplicate());
_is_init = true; m_is_init = true;
} }
void Font::destroy() void Font::Destroy()
{ {
MLX_PROFILE_FUNCTION(); MLX_PROFILE_FUNCTION();
_atlas.destroy(); m_atlas.Destroy();
_is_init = false; m_is_init = false;
} }
Font::~Font() Font::~Font()
{ {
if(_is_init) if(m_is_init)
destroy(); destroy();
} }
} }

View File

@@ -1,16 +1,16 @@
/* ************************************************************************** */ /* ************************************************************************** */
/* */ /* */
/* ::: :::::::: */ /* ::: :::::::: */
/* font_library.cpp :+: :+: :+: */ /* FontLibrary.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2024/01/18 09:28:14 by maldavid #+# #+# */ /* Created: 2024/01/18 09:28:14 by maldavid #+# #+# */
/* Updated: 2024/03/25 19:03:57 by maldavid ### ########.fr */ /* Updated: 2024/04/23 22:59:16 by maldavid ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include <pre_compiled.h> #include <PreCompiled.h>
#include <renderer/texts/font_library.h> #include <renderer/texts/font_library.h>
#include <renderer/texts/font.h> #include <renderer/texts/font.h>