diff --git a/includes/mlx_profile.h b/includes/mlx_profile.h index 9dd8577..18ea4c1 100644 --- a/includes/mlx_profile.h +++ b/includes/mlx_profile.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/10 08:49:17 by maldavid #+# #+# */ -/* Updated: 2024/03/27 18:25:59 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 18:28:12 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -148,10 +148,20 @@ #endif #endif +#include + +#define MLX_MAKE_VERSION(major, minor, patch) ((((uint32_t)(major)) << 22U) | (((uint32_t)(minor)) << 12U) | ((uint32_t)(patch))) + +#define MLX_VERSION_MAJOR(version) (((uint32_t)(version) >> 22U) & 0x7FU) +#define MLX_VERSION_MINOR(version) (((uint32_t)(version) >> 12U) & 0x3FFU) +#define MLX_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU) + +#define MLX_VERSION MLX_MAKE_VERSION(2, 0, 0) +#define MLX_TARGET_VULKAN_API_VERSION MLX_MAKE_VERSION(1, 2, 0) + // Checking common assumptions #ifdef __cplusplus #include - #include static_assert(CHAR_BIT == 8, "CHAR_BIT is expected to be 8"); @@ -169,7 +179,6 @@ #include #endif #include - #include static_assert(CHAR_BIT == 8, "CHAR_BIT is expected to be 8"); @@ -186,7 +195,6 @@ #define STATIC_ASSERT(COND, MSG) typedef char static_assertion___##MSG[(COND)?1:-1] #include - #include STATIC_ASSERT(CHAR_BIT == 8, CHAR_BIT_is_expected_to_be_8); diff --git a/runtime/Includes/Core/Application.h b/runtime/Includes/Core/Application.h index 25d369e..316dc68 100644 --- a/runtime/Includes/Core/Application.h +++ b/runtime/Includes/Core/Application.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 21:49:46 by maldavid #+# #+# */ -/* Updated: 2024/04/03 15:05:24 by maldavid ### ########.fr */ +/* Updated: 2024/04/21 20:39:33 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,6 +16,7 @@ #include #include #include +#include #include namespace mlx @@ -59,11 +60,11 @@ namespace mlx private: FpsManager m_fps; + Input m_in; DriverLoader m_driver_loader; - std::list m_textures; + ImageRegistry m_image_registry; std::vector> m_graphics; std::function f_loop_hook; - std::unique_ptr p_in; void* p_param = nullptr; }; } diff --git a/runtime/Includes/Core/Application.inl b/runtime/Includes/Core/Application.inl index 2457c5b..cd95318 100644 --- a/runtime/Includes/Core/Application.inl +++ b/runtime/Includes/Core/Application.inl @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* application.inl :+: :+: :+: */ +/* Application.inl :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 21:49:46 by maldavid #+# #+# */ -/* Updated: 2023/04/02 14:56:27 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 14:45:07 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -30,12 +30,9 @@ Error("invalid image ptr (NULL)"); \ retval; \ } \ - else if(std::find_if(_textures.begin(), _textures.end(), [=](const Texture& texture) \ - { \ - return &texture == img; \ - }) == _textures.end()) \ + else if(m_image_registry.Find(img)) \ { \ - Error(e_kind::error, "invalid image ptr"); \ + Error("invalid image ptr"); \ retval; \ } else {} @@ -65,7 +62,7 @@ namespace mlx Warning("trying to add event hook for a window that is targeting an image and not a real window, this is not allowed (hook ignored)"); return; } - p_in->OnEvent(m_graphics[*static_cast(win)]->GetWindow()->GetID(), event, funct_ptr, param); + m_in.OnEvent(m_graphics[*static_cast(win)]->GetWindow()->GetID(), event, funct_ptr, param); } void Application::GetScreenSize(void* win, int* w, int* h) noexcept @@ -97,7 +94,7 @@ namespace mlx return nullptr; } m_graphics.emplace_back(std::make_unique(w, h, title, m_graphics.size())); - p_in->RegisterWindow(m_graphics.back()->GetWindow()); + m_in.RegisterWindow(m_graphics.back()->GetWindow()); } return static_cast(&m_graphics.back()->GetID()); } diff --git a/runtime/Includes/Core/Graphics.h b/runtime/Includes/Core/Graphics.h index 9c60f82..e29ce56 100644 --- a/runtime/Includes/Core/Graphics.h +++ b/runtime/Includes/Core/Graphics.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/02 14:49:49 by maldavid #+# #+# */ -/* Updated: 2024/03/27 21:16:11 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 14:02:48 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -42,13 +42,14 @@ namespace mlx inline void LoadFont(const std::filesystem::path& filepath, float scale); inline void TryEraseTextureFromManager(NonOwningPtr texture) noexcept; - inline bool HasWindow() const noexcept { return _has_window; } + inline bool HasWindow() const noexcept { return m_has_window; } - inline Renderer& GetRenderer() { return *_renderer; } + inline Renderer& GetRenderer() { return m_renderer; } ~GraphicsSupport(); private: + Renderer m_renderer; PixelPutPipeline m_pixel_put_pipeline; std::vector> m_drawlist; @@ -59,7 +60,6 @@ namespace mlx glm::mat4 m_proj = glm::mat4(1.0); std::shared_ptr p_window; - std::unique_ptr p_renderer; std::size_t m_width = 0; std::size_t m_height = 0; diff --git a/runtime/Includes/Core/ImagesManager.h b/runtime/Includes/Core/ImagesRegistry.h similarity index 57% rename from runtime/Includes/Core/ImagesManager.h rename to runtime/Includes/Core/ImagesRegistry.h index 46e223d..e2bd494 100644 --- a/runtime/Includes/Core/ImagesManager.h +++ b/runtime/Includes/Core/ImagesRegistry.h @@ -1,27 +1,36 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* ImagesManager.h :+: :+: :+: */ +/* ImagesRegistry.h :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/03 15:11:47 by maldavid #+# #+# */ -/* Updated: 2024/04/21 15:13:43 by maldavid ### ########.fr */ +/* Updated: 2024/04/21 20:31:00 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ -#ifndef __MLX_CORE_IMAGES_MANAGER__ -#define __MLX_CORE_IMAGES_MANAGER__ +#ifndef __MLX_CORE_IMAGES_REGISTRY__ +#define __MLX_CORE_IMAGES_REGISTRY__ namespace mlx { - class ImagesManager + class ImageRegistry { public: + ImageRegistry() = default; + + inline void RegisterTexture(NonOwningPtr texture); + inline void UnregisterTexture(NonOwningPtr texture); + inline bool IsTextureKnown(NonOwningPtr texture); + + ~ImageRegistry() = default; private: - std::unordered_set m_textures_registry; + std::unordered_set> m_textures_registry; }; } +#include + #endif diff --git a/runtime/Includes/Core/ImagesRegistry.inl b/runtime/Includes/Core/ImagesRegistry.inl new file mode 100644 index 0000000..2a69334 --- /dev/null +++ b/runtime/Includes/Core/ImagesRegistry.inl @@ -0,0 +1,25 @@ +// This file is a part of Akel +// Authors : @kbz_8 +// Created : 21/04/2024 +// Updated : 21/04/2024 + +#pragma once +#include + +namespace mlx +{ + void ImageRegistry::RegisterTexture(NonOwningPtr texture) + { + m_textures_registry.insert(texture); + } + + void ImageRegistry::UnregisterTexture(NonOwningPtr texture) + { + m_textures_registry.erase(texture); + } + + bool ImageRegistry::IsTextureKnown(NonOwningPtr texture) + { + return m_textures_registry.find(texture) != m_textures_registry.end(); + } +} diff --git a/runtime/Includes/PreCompiled.h b/runtime/Includes/PreCompiled.h index dd0f386..07647ff 100644 --- a/runtime/Includes/PreCompiled.h +++ b/runtime/Includes/PreCompiled.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/03/25 17:37:23 by maldavid #+# #+# */ -/* Updated: 2024/03/27 21:33:47 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 13:49:52 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -23,7 +23,7 @@ #include #include -#ifdef LEGACY +#ifdef MLX_LEGACY #include #include #else @@ -84,6 +84,6 @@ #include #include #include -#include +#include #endif diff --git a/runtime/Includes/Renderer/Buffers/Buffer.h b/runtime/Includes/Renderer/Buffers/Buffer.h index 5acf9de..f8532ab 100644 --- a/runtime/Includes/Renderer/Buffers/Buffer.h +++ b/runtime/Includes/Renderer/Buffers/Buffer.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/06 23:18:52 by maldavid #+# #+# */ -/* Updated: 2024/03/27 22:09:07 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 14:20:49 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -27,9 +27,9 @@ namespace mlx void Create(BufferType type, VkDeviceSize size, VkBufferUsageFlags usage, const char* name, const void* data = nullptr); void Destroy() noexcept; - inline void MapMem(void** data) noexcept { Render_Core::get().getAllocator().mapMemory(m_allocation, data); m_is_mapped = true; } + inline void MapMem(void** data) noexcept { RenderCore::Get().GetAllocator().MapMemory(m_allocation, data); m_is_mapped = true; } inline bool IsMapped() const noexcept { return m_is_mapped; } - inline void UnmapMem() noexcept { Render_Core::get().getAllocator().unmapMemory(m_allocation); m_is_mapped = false; } + inline void UnmapMem() noexcept { RenderCore::Get().GetAllocator().UnmapMemory(m_allocation); m_is_mapped = false; } void Flush(VkDeviceSize size = VK_WHOLE_SIZE, VkDeviceSize offset = 0); bool CopyFromBuffer(const Buffer& buffer) noexcept; diff --git a/runtime/Includes/Renderer/Buffers/UniformBuffer.h b/runtime/Includes/Renderer/Buffers/UniformBuffer.h index 77b1f3a..6b84cd5 100644 --- a/runtime/Includes/Renderer/Buffers/UniformBuffer.h +++ b/runtime/Includes/Renderer/Buffers/UniformBuffer.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/06 18:45:29 by maldavid #+# #+# */ -/* Updated: 2024/03/27 22:15:23 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 14:23:56 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -43,7 +43,7 @@ namespace mlx private: std::array m_buffers; std::array m_maps; - NonOwningPtr m_renderer; + NonOwningPtr p_renderer; }; } diff --git a/runtime/Includes/Renderer/Command/CommandBuffer.h b/runtime/Includes/Renderer/Command/CommandBuffer.h index 68c068f..b5be0ad 100644 --- a/runtime/Includes/Renderer/Command/CommandBuffer.h +++ b/runtime/Includes/Renderer/Command/CommandBuffer.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/06 18:25:42 by maldavid #+# #+# */ -/* Updated: 2024/03/27 22:44:58 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 17:59:50 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -29,7 +29,7 @@ namespace mlx void Destroy() noexcept; void BeginRecord(VkCommandBufferUsageFlags usage = 0); - void Submit(class Semaphore* semaphores) noexcept; + void Submit(NonOwningPtr signal, NonOwningPtr wait) noexcept; void SubmitIdle(bool shouldWaitForExecution = true) noexcept; // TODO : handle `shouldWaitForExecution` as false by default (needs to modify CmdResources lifetimes to do so) void UpdateSubmitState() noexcept; inline void WaitForExecution() noexcept { m_fence.wait(); UpdateSubmitState(); m_state = CommandBufferState::Ready; } @@ -58,7 +58,7 @@ namespace mlx void PostTransferBarrier() noexcept; private: - std::vector m_cmd_resources; + std::vector> m_cmd_resources; Fence m_fence; VkCommandBuffer m_cmd_buffer = VK_NULL_HANDLE; NonOwningPtr m_pool; diff --git a/runtime/Includes/Renderer/Core/DrawableResource.h b/runtime/Includes/Renderer/Core/DrawableResource.h index fb60df9..a043d3a 100644 --- a/runtime/Includes/Renderer/Core/DrawableResource.h +++ b/runtime/Includes/Renderer/Core/DrawableResource.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/10 21:00:37 by maldavid #+# #+# */ -/* Updated: 2024/03/27 22:47:32 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 18:10:56 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,7 +19,7 @@ namespace mlx { public: DrawableResource() = default; - virtual void Render(std::array& sets, class Renderer& renderer) = 0; + virtual void Render(class Renderer& renderer) = 0; virtual void ResetUpdate() {} virtual ~DrawableResource() = default; }; diff --git a/runtime/Includes/Renderer/Core/Instance.h b/runtime/Includes/Renderer/Core/Instance.h index 9b33f3e..cecb73d 100644 --- a/runtime/Includes/Renderer/Core/Instance.h +++ b/runtime/Includes/Renderer/Core/Instance.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/08 19:03:04 by maldavid #+# #+# */ -/* Updated: 2024/03/27 22:48:55 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 18:44:02 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,6 +21,8 @@ namespace mlx void Init(); void Destroy() noexcept; + inline std::uint32_t GetInstanceVersion() const noexcept { return m_instance_version; } + inline VkInstance& operator()() noexcept { return m_instance; } inline VkInstance& Get() noexcept { return m_instance; } @@ -29,6 +31,7 @@ namespace mlx private: VkInstance m_instance = VK_NULL_HANDLE; + std::uint32_t m_instance_version = 0; }; } diff --git a/runtime/Includes/Renderer/Core/ValidationLayers.h b/runtime/Includes/Renderer/Core/ValidationLayers.h index cee5999..0dc3e45 100644 --- a/runtime/Includes/Renderer/Core/ValidationLayers.h +++ b/runtime/Includes/Renderer/Core/ValidationLayers.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/12/19 14:04:25 by maldavid #+# #+# */ -/* Updated: 2024/03/27 22:59:00 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 19:16:25 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,10 +22,10 @@ namespace mlx void Init(); void Destroy(); - + bool CheckValidationLayerSupport(); void PopulateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& create_info); - + VkResult SetDebugUtilsObjectNameEXT(VkObjectType object_type, std::uint64_t object_handle, const char* object_name); ~ValidationLayers() = default; diff --git a/runtime/Includes/Renderer/Descriptors/DescriptorPool.h b/runtime/Includes/Renderer/Descriptors/DescriptorPool.h index 97cabe9..1b09905 100644 --- a/runtime/Includes/Renderer/Descriptors/DescriptorPool.h +++ b/runtime/Includes/Renderer/Descriptors/DescriptorPool.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/01/23 18:32:43 by maldavid #+# #+# */ -/* Updated: 2024/03/27 23:00:29 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 19:36:03 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,8 +20,9 @@ namespace mlx public: DescriptorPool() = default; - void Init(std::size_t n, NonOwningPtr size); - void FreeDescriptor(const class DescriptorSet& set); + void Init(std::vector sizes); + VkDescriptorSet AllocateDescriptorSet(class DescriptorSetLayout& layout); + void FreeDescriptor(VkDescriptorSet set); void Destroy() noexcept; inline VkDescriptorPool& operator()() noexcept { return m_pool; } diff --git a/runtime/Includes/Renderer/Descriptors/DescriptorPoolManager.h b/runtime/Includes/Renderer/Descriptors/DescriptorPoolManager.h index 8f4cb01..5c032aa 100644 --- a/runtime/Includes/Renderer/Descriptors/DescriptorPoolManager.h +++ b/runtime/Includes/Renderer/Descriptors/DescriptorPoolManager.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/20 06:26:26 by maldavid #+# #+# */ -/* Updated: 2024/03/27 23:00:56 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 19:40:22 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,7 +22,7 @@ namespace mlx public: DescriptorPoolManager() = default; - DescriptorPool& GetAvailablePool(); // assumes the pool is for only one set allocation, may cause some issues if this is for more than one + DescriptorPool& GetAvailablePool(); void DestroyAllPools(); ~DescriptorPoolManager() = default; diff --git a/runtime/Includes/Renderer/Descriptors/DescriptorSet.h b/runtime/Includes/Renderer/Descriptors/DescriptorSet.h index 56c8ec4..11b41a0 100644 --- a/runtime/Includes/Renderer/Descriptors/DescriptorSet.h +++ b/runtime/Includes/Renderer/Descriptors/DescriptorSet.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/01/23 18:39:36 by maldavid #+# #+# */ -/* Updated: 2024/03/27 23:02:38 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 19:49:02 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,6 +14,7 @@ #define __VK_DESCRIPTOR_SET__ #include +#include namespace mlx { @@ -22,7 +23,7 @@ namespace mlx public: DescriptorSet() = default; - void Init(class Renderer* renderer, class DescriptorPool* pool, class DescriptorSetLayout* layout); + void Init(NonOwningPtr renderer, NonOwningPtr pool, DescriptorSetLayout layout); void WriteDescriptor(int binding, NonOwningPtr ubo) const noexcept; void WriteDescriptor(int binding, const class Image& image) const noexcept; @@ -41,9 +42,9 @@ namespace mlx ~DescriptorSet() = default; private: + DescriptorSetLayout p_layout; std::array m_desc_set; NonOwningPtr p_pool; - NonOwningPtr p_layout; NonOwningPtr p_renderer; }; } diff --git a/runtime/Includes/Renderer/Descriptors/DescriptorSetLayout.h b/runtime/Includes/Renderer/Descriptors/DescriptorSetLayout.h index e06bd54..c53cfdf 100644 --- a/runtime/Includes/Renderer/Descriptors/DescriptorSetLayout.h +++ b/runtime/Includes/Renderer/Descriptors/DescriptorSetLayout.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/01/23 18:36:22 by maldavid #+# #+# */ -/* Updated: 2024/03/27 23:03:04 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 19:50:50 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/runtime/Includes/Renderer/Images/Image.h b/runtime/Includes/Renderer/Images/Image.h index 6f93bed..2f71614 100644 --- a/runtime/Includes/Renderer/Images/Image.h +++ b/runtime/Includes/Renderer/Images/Image.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/01/25 11:54:21 by maldavid #+# #+# */ -/* Updated: 2024/03/28 22:08:35 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 20:00:53 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -45,7 +45,7 @@ namespace mlx void CreateSampler() noexcept; void CopyFromBuffer(class Buffer& buffer); void CopyToBuffer(class Buffer& buffer); - void TransitionLayout(VkImageLayout new_layout, CmdBuffer* cmd = nullptr); + void TransitionLayout(VkImageLayout new_layout, NonOwningPtr cmd = nullptr); virtual void Destroy() noexcept; inline VkImage Get() noexcept { return m_image; } diff --git a/runtime/Includes/Renderer/Images/Texture.h b/runtime/Includes/Renderer/Images/Texture.h index 7c88e17..16091a5 100644 --- a/runtime/Includes/Renderer/Images/Texture.h +++ b/runtime/Includes/Renderer/Images/Texture.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/03/08 02:24:58 by maldavid #+# #+# */ -/* Updated: 2024/03/28 22:11:21 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 20:03:59 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -26,15 +26,15 @@ namespace mlx Texture() = default; void Create(std::uint8_t* pixels, std::uint32_t width, std::uint32_t height, VkFormat format, const char* name, bool dedicated_memory = false); - void Render(std::array& sets, class Renderer& renderer, int x, int y); + void Render(class Renderer& renderer, int x, int y); void Destroy() noexcept override; void SetPixel(int x, int y, std::uint32_t color) noexcept; int GetPixel(int x, int y) noexcept; inline void SetDescriptor(DescriptorSet&& set) noexcept { m_set = set; } - inline VkDescriptorSet GetSet() noexcept { return m_set.isInit() ? m_set.get() : VK_NULL_HANDLE; } - inline void UpdateSet(int binding) noexcept { m_set.writeDescriptor(binding, *this); m_has_set_been_updated = true; } + inline VkDescriptorSet GetSet() noexcept { return m_set.IsInit() ? m_set.get() : VK_NULL_HANDLE; } + inline void UpdateSet(int binding) noexcept { m_set.WriteDescriptor(binding, *this); m_has_set_been_updated = true; } inline bool HasBeenUpdated() const noexcept { return m_has_set_been_updated; } inline constexpr void ResetUpdate() noexcept { m_has_set_been_updated = false; } @@ -57,7 +57,7 @@ namespace mlx bool m_has_set_been_updated = false; }; - Texture StbTextureLoad(std::filesystem::path file, int* w, int* h); + Texture* StbTextureLoad(std::filesystem::path file, int* w, int* h); } #endif diff --git a/runtime/Includes/Utils/NonOwningPtr.h b/runtime/Includes/Utils/NonOwningPtr.h index baef061..2acc906 100644 --- a/runtime/Includes/Utils/NonOwningPtr.h +++ b/runtime/Includes/Utils/NonOwningPtr.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/03/27 21:03:37 by maldavid #+# #+# */ -/* Updated: 2024/03/27 21:05:05 by maldavid ### ########.fr */ +/* Updated: 2024/04/21 20:21:56 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -42,4 +42,16 @@ namespace mlx #include +namespace std +{ + template + struct hash> + { + std::size_t operator()(const mlx::NonOwningPtr& ptr) const noexcept + { + return std::hash{}(ptr.Get()); + } + }; +} + #endif diff --git a/runtime/Sources/Core/Application.cpp b/runtime/Sources/Core/Application.cpp index ab2a4aa..d0c754b 100644 --- a/runtime/Sources/Core/Application.cpp +++ b/runtime/Sources/Core/Application.cpp @@ -6,103 +6,110 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 22:10:52 by maldavid #+# #+# */ -/* Updated: 2024/04/02 17:06:34 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 15:06:26 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include -namespace mlx::core +namespace mlx { - Application::Application() : _fps(), _in(std::make_unique()) + Application::Application() : m_fps(), m_in() { EventBus::RegisterListener({[](const EventBase& event) { - }, "__internal_application" }); - _fps.init(); + m_fps.init(); } - void Application::run() noexcept + void Application::Run() noexcept { - while(_in->isRunning()) + m_in.Run(); + + while(m_in.IsRunning()) { - if(!_fps.update()) + if(!m_fps.Update()) continue; - _in->update(); + m_in.Update(); - if(_loop_hook) - _loop_hook(_param); + if(f_loop_hook) + f_loop_hook(p_param); - for(auto& gs : _graphics) - gs->render(); + for(auto& gs : m_graphics) + { + if(gs) + gs->Render(); + } } - Render_Core::get().getSingleTimeCmdManager().updateSingleTimesCmdBuffersSubmitState(); + RenderCore::Get().GetSingleTimeCmdManager().UpdateSingleTimesCmdBuffersSubmitState(); - for(auto& gs : _graphics) + for(auto& gs : m_graphics) { + if(!gs) + continue; for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) - gs->getRenderer().getCmdBuffer(i).waitForExecution(); + gs->GetRenderer().GetCmdBuffer(i).WaitForExecution(); } } - void* Application::newTexture(int w, int h) + void* Application::NewTexture(int w, int h) { MLX_PROFILE_FUNCTION(); + Texture* texture = new Texture; #ifdef DEBUG - _textures.emplace_front().create(nullptr, w, h, VK_FORMAT_R8G8B8A8_UNORM, "__mlx_unamed_user_texture"); + texture->Create(nullptr, w, h, VK_FORMAT_R8G8B8A8_UNORM, "__mlx_unamed_user_texture"); #else - _textures.emplace_front().create(nullptr, w, h, VK_FORMAT_R8G8B8A8_UNORM, nullptr); + texture->Create(nullptr, w, h, VK_FORMAT_R8G8B8A8_UNORM, nullptr); #endif - return &_textures.front(); + m_image_registry.RegisterTexture(texture); + return texture; } - void* Application::newStbTexture(char* file, int* w, int* h) + void* Application::NewStbTexture(char* file, int* w, int* h) { MLX_PROFILE_FUNCTION(); - _textures.emplace_front(stbTextureLoad(file, w, h)); - return &_textures.front(); + Texture* texture = StbTextureLoad(file, w, h); + m_image_registry.RegisterTexture(texture); + return texture; } - void Application::destroyTexture(void* ptr) + void Application::DestroyTexture(void* ptr) { MLX_PROFILE_FUNCTION(); - vkDeviceWaitIdle(Render_Core::get().getDevice().get()); // TODO : synchronize with another method than waiting for GPU to be idle - if(ptr == nullptr) + vkDeviceWaitIdle(RenderCore::Get().GetDevice().Get()); // TODO : synchronize with another method than waiting for GPU to be idle + if(!m_image_registry.Find(ptr)) { - core::error::report(e_kind::error, "invalid image ptr (NULL)"); + Error("invalid image ptr"); return; } - auto it = std::find_if(_textures.begin(), _textures.end(), [=](const Texture& texture) { return &texture == ptr; }); - if(it == _textures.end()) - { - core::error::report(e_kind::error, "invalid image ptr"); - return; - } Texture* texture = static_cast(ptr); - if(!texture->isInit()) - core::error::report(e_kind::error, "trying to destroy a texture that has already been destroyed"); + if(!texture->IsInit()) + Error("trying to destroy a texture that has already been destroyed"); else - texture->destroy(); + texture->Destroy(); for(auto& gs : _graphics) - gs->tryEraseTextureFromManager(texture); - _textures.erase(it); + { + if(gs) + gs->TryEraseTextureFromManager(texture); + } + m_image_registry.UnregisterTexture(texture); + delete texture; } Application::~Application() { - TextLibrary::get().clearLibrary(); - FontLibrary::get().clearLibrary(); + TextLibrary::Get().ClearLibrary(); + FontLibrary::Get().ClearLibrary(); } } diff --git a/runtime/Sources/Core/Bridge.cpp b/runtime/Sources/Core/Bridge.cpp index f81b738..6a550bc 100644 --- a/runtime/Sources/Core/Bridge.cpp +++ b/runtime/Sources/Core/Bridge.cpp @@ -1,29 +1,27 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* bridge.cpp :+: :+: :+: */ +/* Bridge.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 17:35:20 by maldavid #+# #+# */ -/* Updated: 2024/03/25 23:05:46 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 14:44:27 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ -#include +#include -#include -#include "errors.h" -#include "application.h" -#include +#include +#include #include -#include +#include static void* __mlx_ptr = nullptr; #define MLX_CHECK_APPLICATION_POINTER(ptr) \ if(ptr != __mlx_ptr || ptr == NULL) \ - mlx::core::error::report(e_kind::fatal_error, "invalid mlx pointer passed to '%s'", MLX_FUNC_SIG); \ + mlx::FatalError("invalid mlx pointer passed to '%'", MLX_FUNC_SIG); \ else {} // just to avoid issues with possible if-else statements outside this macro extern "C" @@ -32,14 +30,14 @@ extern "C" { if(__mlx_ptr != nullptr) { - mlx::core::error::report(e_kind::error, "MLX cannot be initialized multiple times"); - return NULL; // not nullptr for the C compatibility + Error("MLX cannot be initialized multiple times"); + return nullptr; } - mlx::MemManager::get(); // just to initialize the C garbage collector - mlx::core::Application* app = new mlx::core::Application; - mlx::Render_Core::get().init(); + mlx::MemManager::Get(); // just to initialize the C garbage collector + mlx::Application* app = new mlx::Application; if(app == nullptr) - mlx::core::error::report(e_kind::fatal_error, "Tout a pété"); + mlx::FatalError("Tout a pété"); + mlx::RenderCore::Get().Init(); __mlx_ptr = static_cast(app); return __mlx_ptr; } @@ -49,30 +47,30 @@ extern "C" MLX_CHECK_APPLICATION_POINTER(mlx); if(w <= 0 || h <= 0) { - mlx::core::error::report(e_kind::fatal_error, "invalid window size (%d x %d)", w, h); + mlx::FatalError("invalid window size (%d x %d)", w, h); return NULL; // not nullptr for the C compatibility } - return static_cast(mlx)->newGraphicsSuport(w, h, title); + return static_cast(mlx)->NewGraphicsSuport(w, h, title); } int mlx_loop_hook(void* mlx, int (*f)(void*), void* param) { MLX_CHECK_APPLICATION_POINTER(mlx); - static_cast(mlx)->loopHook(f, param); + static_cast(mlx)->LoopHook(f, param); return 0; } int mlx_loop(void* mlx) { MLX_CHECK_APPLICATION_POINTER(mlx); - static_cast(mlx)->run(); + static_cast(mlx)->Run(); return 0; } int mlx_loop_end(void* mlx) { MLX_CHECK_APPLICATION_POINTER(mlx); - static_cast(mlx)->loopEnd(); + static_cast(mlx)->LoopEnd(); return 0; } @@ -89,21 +87,21 @@ extern "C" int mlx_mouse_move(void* mlx, void* win, int x, int y) { MLX_CHECK_APPLICATION_POINTER(mlx); - static_cast(mlx)->mouseMove(win, x, y); + static_cast(mlx)->MouseMove(win, x, y); return 0; } int mlx_mouse_get_pos(void* mlx, int* x, int* y) { MLX_CHECK_APPLICATION_POINTER(mlx); - static_cast(mlx)->getMousePos(x, y); + static_cast(mlx)->GetMousePos(x, y); return 0; } int mlx_on_event(void* mlx, void* win, mlx_event_type event, int (*funct_ptr)(int, void*), void* param) { MLX_CHECK_APPLICATION_POINTER(mlx); - static_cast(mlx)->onEvent(win, static_cast(event), funct_ptr, param); + static_cast(mlx)->OnEvent(win, static_cast(event), funct_ptr, param); return 0; } @@ -111,14 +109,17 @@ extern "C" { MLX_CHECK_APPLICATION_POINTER(mlx); if (width <= 0 || height <= 0) - mlx::core::error::report(e_kind::fatal_error, "invalid image size (%d x %d)", width, height); - return static_cast(mlx)->newTexture(width, height); + { + mlx::Error("invalid image size (% x %)", width, height); + return nullptr; + } + return static_cast(mlx)->NewTexture(width, height); } int mlx_get_image_pixel(void* mlx, void* img, int x, int y) { MLX_CHECK_APPLICATION_POINTER(mlx); - int color = static_cast(mlx)->getTexturePixel(img, x, y); + int color = static_cast(mlx)->GetTexturePixel(img, x, y); unsigned char color_bits[4]; color_bits[0] = (color & 0x000000FF); color_bits[1] = (color & 0x0000FF00) >> 8; @@ -135,20 +136,20 @@ extern "C" color_bits[1] = (color & 0x0000FF00) >> 8; color_bits[2] = (color & 0x000000FF); color_bits[3] = (color & 0xFF000000) >> 24; - static_cast(mlx)->setTexturePixel(img, x, y, *reinterpret_cast(color_bits)); + static_cast(mlx)->SetTexturePixel(img, x, y, *reinterpret_cast(color_bits)); } int mlx_put_image_to_window(void* mlx, void* win, void* img, int x, int y) { MLX_CHECK_APPLICATION_POINTER(mlx); - static_cast(mlx)->texturePut(win, img, x, y); + static_cast(mlx)->TexturePut(win, img, x, y); return 0; } int mlx_destroy_image(void* mlx, void* img) { MLX_CHECK_APPLICATION_POINTER(mlx); - static_cast(mlx)->destroyTexture(img); + static_cast(mlx)->DestroyTexture(img); return 0; } @@ -156,42 +157,51 @@ extern "C" { MLX_CHECK_APPLICATION_POINTER(mlx); if (filename == nullptr) - mlx::core::error::report(e_kind::fatal_error, "PNG loader : filename is NULL"); + { + mlx::Error("PNG loader : filename is NULL"); + return nullptr; + } std::filesystem::path file(filename); if(file.extension() != ".png") { - mlx::core::error::report(e_kind::error, "PNG loader : not a png file '%s'", filename); + mlx::Error("PNG loader : not a png file '%'", filename); return nullptr; } - return static_cast(mlx)->newStbTexture(filename, width, height); + return static_cast(mlx)->NewStbTexture(filename, width, height); } void* mlx_jpg_file_to_image(void* mlx, char* filename, int* width, int* height) { MLX_CHECK_APPLICATION_POINTER(mlx); if (filename == nullptr) - mlx::core::error::report(e_kind::fatal_error, "JPG loader : filename is NULL"); + { + mlx::Error("JPG loader : filename is NULL"); + return nullptr; + } std::filesystem::path file(filename); if(file.extension() != ".jpg" && file.extension() != ".jpeg") { - mlx::core::error::report(e_kind::error, "JPG loader : not a jpg file '%s'", filename); + mlx::Error("JPG loader : not a jpg file '%'", filename); return nullptr; } - return static_cast(mlx)->newStbTexture(filename, width, height); + return static_cast(mlx)->NewStbTexture(filename, width, height); } void* mlx_bmp_file_to_image(void* mlx, char* filename, int* width, int* height) { MLX_CHECK_APPLICATION_POINTER(mlx); if (filename == nullptr) - mlx::core::error::report(e_kind::fatal_error, "BMP loader : filename is NULL"); + { + mlx::Error("BMP loader : filename is NULL"); + return nullptr; + } std::filesystem::path file(filename); if(file.extension() != ".bmp" && file.extension() != ".dib") { - mlx::core::error::report(e_kind::error, "BMP loader : not a bmp file '%s'", filename); + mlx::Error("BMP loader : not a bmp file '%'", filename); return nullptr; } - return static_cast(mlx)->newStbTexture(filename, width, height); + return static_cast(mlx)->NewStbTexture(filename, width, height); } int mlx_pixel_put(void* mlx, void* win, int x, int y, int color) @@ -202,7 +212,7 @@ extern "C" color_bits[1] = (color & 0x0000FF00) >> 8; color_bits[2] = (color & 0x000000FF); color_bits[3] = (color & 0xFF000000) >> 24; - static_cast(mlx)->pixelPut(win, x, y, *reinterpret_cast(color_bits)); + static_cast(mlx)->PixelPut(win, x, y, *reinterpret_cast(color_bits)); return 0; } @@ -214,7 +224,7 @@ extern "C" color_bits[1] = (color & 0x0000FF00) >> 8; color_bits[2] = (color & 0x000000FF); color_bits[3] = (color & 0xFF000000) >> 24; - static_cast(mlx)->stringPut(win, x, y, *reinterpret_cast(color_bits), str); + static_cast(mlx)->StringPut(win, x, y, *reinterpret_cast(color_bits), str); return 0; } @@ -223,19 +233,19 @@ extern "C" MLX_CHECK_APPLICATION_POINTER(mlx); if (filepath == nullptr) { - mlx::core::error::report(e_kind::error, "Font loader : filepath is NULL"); + mlx::Error("Font loader : filepath is NULL"); return; } std::filesystem::path file(filepath); 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); + mlx::Error("TTF loader : not a truetype font file '%'", filepath); return; } if(std::strcmp(filepath, "default") == 0) - static_cast(mlx)->loadFont(win, file, 6.f); + static_cast(mlx)->LoadFont(win, file, 6.f); else - static_cast(mlx)->loadFont(win, file, 16.f); + static_cast(mlx)->LoadFont(win, file, 16.f); } void mlx_set_font_scale(void* mlx, void* win, char* filepath, float scale) @@ -243,37 +253,37 @@ extern "C" MLX_CHECK_APPLICATION_POINTER(mlx); if (filepath == nullptr) { - mlx::core::error::report(e_kind::error, "Font loader : filepath is NULL"); + mlx::Error("Font loader : filepath is NULL"); return; } std::filesystem::path file(filepath); 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); + mlx::Error("TTF loader : not a truetype font file '%'", filepath); return; } - static_cast(mlx)->loadFont(win, file, scale); + static_cast(mlx)->LoadFont(win, file, scale); } int mlx_clear_window(void* mlx, void* win) { MLX_CHECK_APPLICATION_POINTER(mlx); - static_cast(mlx)->clearGraphicsSupport(win); + static_cast(mlx)->ClearGraphicsSupport(win); return 0; } int mlx_destroy_window(void* mlx, void* win) { MLX_CHECK_APPLICATION_POINTER(mlx); - static_cast(mlx)->destroyGraphicsSupport(win); + static_cast(mlx)->DestroyGraphicsSupport(win); return 0; } int mlx_destroy_display(void* mlx) { MLX_CHECK_APPLICATION_POINTER(mlx); - delete static_cast(mlx); - mlx::Render_Core::get().destroy(); + delete static_cast(mlx); + mlx::RenderCore::Get().Destroy(); __mlx_ptr = nullptr; return 0; } @@ -281,7 +291,7 @@ extern "C" int mlx_get_screens_size(void* mlx, void* win, int* w, int* h) { MLX_CHECK_APPLICATION_POINTER(mlx); - static_cast(mlx)->getScreenSize(win, w, h); + static_cast(mlx)->GetScreenSize(win, w, h); return 0; } @@ -290,15 +300,15 @@ extern "C" MLX_CHECK_APPLICATION_POINTER(mlx); if(fps < 0) { - mlx::core::error::report(e_kind::error, "You cannot set a negative FPS cap (nice try)"); - fps = -fps; + mlx::Error("You cannot set a negative FPS cap (nice try)"); + return 0; } if(fps == 0) { - mlx::core::error::report(e_kind::error, "You cannot set a FPS cap to 0 (nice try)"); + mlx::Error("You cannot set a FPS cap to 0 (nice try)"); return 0; } - static_cast(mlx)->setFPSCap(static_cast(fps)); + static_cast(mlx)->SetFPSCap(static_cast(fps)); return 0; } } diff --git a/runtime/Sources/Core/Graphics.cpp b/runtime/Sources/Core/Graphics.cpp index 6be4395..b9ea623 100644 --- a/runtime/Sources/Core/Graphics.cpp +++ b/runtime/Sources/Core/Graphics.cpp @@ -1,73 +1,68 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* graphics.cpp :+: :+: :+: */ +/* Graphics.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/02 15:13:55 by maldavid #+# #+# */ -/* Updated: 2024/03/27 00:32:34 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 14:03:51 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ -#include +#include -#include +#include namespace mlx { - GraphicsSupport::GraphicsSupport(std::size_t w, std::size_t h, Texture* render_target, int id) : - _window(nullptr), - _renderer(std::make_unique()), - _width(w), - _height(h), - _id(id), - _has_window(false) + GraphicsSupport::GraphicsSupport(std::size_t w, std::size_t h, NonOwningPtr render_target, int id) : + p_window(nullptr), + m_width(w), + m_height(h), + m_id(id), + m_has_window(false) { MLX_PROFILE_FUNCTION(); - _renderer->setWindow(nullptr); - _renderer->init(render_target); - _pixel_put_pipeline.init(w, h, *_renderer); - _text_manager.init(*_renderer); + m_renderer.SetWindow(nullptr); + m_renderer.Init(render_target); + m_pixel_put_pipeline.Init(w, h, m_renderer); + m_text_manager.Init(m_renderer); } GraphicsSupport::GraphicsSupport(std::size_t w, std::size_t h, std::string title, int id) : - _window(std::make_shared(w, h, title)), - _renderer(std::make_unique()), - _width(w), - _height(h), - _id(id), - _has_window(true) + p_window(std::make_shared(w, h, title)), + m_width(w), + m_height(h), + m_id(id), + m_has_window(true) { MLX_PROFILE_FUNCTION(); - _renderer->setWindow(_window.get()); - _renderer->init(nullptr); - _pixel_put_pipeline.init(w, h, *_renderer); - _text_manager.init(*_renderer); + m_renderer.SetWindow(p_window.get()); + m_renderer.Init(nullptr); + m_pixel_put_pipeline.Init(w, h, m_renderer); + m_text_manager.Init(m_renderer); } - void GraphicsSupport::render() noexcept + void GraphicsSupport::Render() noexcept { MLX_PROFILE_FUNCTION(); - if(!_renderer->beginFrame()) + if(!m_renderer.BeginFrame()) return; - _proj = glm::ortho(0, _width, 0, _height); - _renderer->getUniformBuffer()->setData(sizeof(_proj), &_proj); + m_proj = glm::ortho(0, m_width, 0, m_height); + m_renderer.GetUniformBuffer()->SetData(sizeof(m_proj), &m_proj); - static std::array sets = { - _renderer->getVertDescriptorSet().get(), - VK_NULL_HANDLE - }; + m_renderer.getVertDescriptorSet().Bind(); + + for(auto& data : m_drawlist) + data->Render(m_renderer); + + m_pixel_put_pipeline.Render(m_renderer); + + m_renderer.EndFrame(); for(auto& data : _drawlist) - data->render(sets, *_renderer); - - _pixel_put_pipeline.render(sets, *_renderer); - - _renderer->endFrame(); - - for(auto& data : _drawlist) - data->resetUpdate(); + data->ResetUpdate(); #ifdef GRAPHICS_MEMORY_DUMP // dump memory to file every two seconds @@ -75,7 +70,7 @@ namespace mlx static std::int64_t timer = static_cast(std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count()); if(std::chrono::duration{static_cast(std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count()) - timer} >= 1s) { - Render_Core::get().getAllocator().dumpMemoryToJson(); + RenderCore::Get().GetAllocator().DumpMemoryToJson(); timer = static_cast(std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count()); } #endif @@ -84,11 +79,11 @@ namespace mlx GraphicsSupport::~GraphicsSupport() { MLX_PROFILE_FUNCTION(); - vkDeviceWaitIdle(Render_Core::get().getDevice().get()); - _text_manager.destroy(); - _pixel_put_pipeline.destroy(); - _renderer->destroy(); - if(_window) - _window->destroy(); + vkDeviceWaitIdle(RenderCore::Get().GetDevice().Get()); + m_text_manager.Destroy(); + m_pixel_put_pipeline.Destroy(); + m_renderer->Destroy(); + if(p_window) + p_window->Destroy(); } } diff --git a/runtime/Sources/Core/Memory.cpp b/runtime/Sources/Core/Memory.cpp index 93ada08..670061b 100644 --- a/runtime/Sources/Core/Memory.cpp +++ b/runtime/Sources/Core/Memory.cpp @@ -1,64 +1,63 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* memory.cpp :+: :+: :+: */ +/* Memory.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/12/07 16:32:01 by kbz_8 #+# #+# */ -/* Updated: 2024/03/25 19:01:02 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 14:05:52 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ -#include +#include -#include -#include +#include namespace mlx { - void* MemManager::malloc(std::size_t size) + void* MemManager::Malloc(std::size_t size) { void* ptr = std::malloc(size); if(ptr != nullptr) - _blocks.push_back(ptr); + s_blocks.push_back(ptr); return ptr; } - void* MemManager::calloc(std::size_t n, std::size_t size) + void* MemManager::Calloc(std::size_t n, std::size_t size) { void* ptr = std::calloc(n, size); if(ptr != nullptr) - _blocks.push_back(ptr); + s_blocks.push_back(ptr); return ptr; } - void* MemManager::realloc(void* ptr, std::size_t size) + void* MemManager::Realloc(void* ptr, std::size_t size) { void* ptr2 = std::realloc(ptr, size); if(ptr2 != nullptr) - _blocks.push_back(ptr2); - auto it = std::find(_blocks.begin(), _blocks.end(), ptr); - if(it != _blocks.end()) - _blocks.erase(it); + s_blocks.push_back(ptr2); + auto it = std::find(s_blocks.begin(), s_blocks.end(), ptr); + if(it != s_blocks.end()) + s_blocks.erase(it); return ptr2; } - void MemManager::free(void* ptr) + void MemManager::Free(void* ptr) { - auto it = std::find(_blocks.begin(), _blocks.end(), ptr); - if(it == _blocks.end()) + auto it = std::find(s_blocks.begin(), s_blocks.end(), ptr); + if(it == s_blocks.end()) { - core::error::report(e_kind::error, "Memory Manager : trying to free a pointer not allocated by the memory manager"); + Error("Memory Manager : trying to free a pointer not allocated by the memory manager"); return; } std::free(*it); - _blocks.erase(it); + s_blocks.erase(it); } MemManager::~MemManager() { - std::for_each(_blocks.begin(), _blocks.end(), [](void* ptr) + std::for_each(s_blocks.begin(), s_blocks.end(), [](void* ptr) { std::free(ptr); }); diff --git a/runtime/Sources/Core/Profiler.cpp b/runtime/Sources/Core/Profiler.cpp index 5ef15cd..e811bc5 100644 --- a/runtime/Sources/Core/Profiler.cpp +++ b/runtime/Sources/Core/Profiler.cpp @@ -1,52 +1,50 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* profiler.cpp :+: :+: :+: */ +/* Profiler.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/10 13:56:21 by maldavid #+# #+# */ -/* Updated: 2024/03/25 19:01:06 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 14:08:51 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ -#include +#include -#include -#include -#include +#include namespace mlx { - void Profiler::beginRuntimeSession() + void Profiler::BeginRuntimeSession() { - std::lock_guard lock(_mutex); - if(_runtime_session_began) + std::lock_guard lock(m_mutex); + if(m_runtime_session_began) return; - _output_stream.open("./runtime_profile.mlx.json", std::ofstream::out | std::ofstream::trunc); + m_output_stream.open("./runtime_profile.mlx.json", std::ofstream::out | std::ofstream::trunc); - if(_output_stream.is_open()) - writeHeader(); + if(m_output_stream.is_open()) + WriteHeader(); else - core::error::report(e_kind::error, "Profiler : cannot open runtime profile file"); - _runtime_session_began = true; + Error("Profiler : cannot open runtime profile file"); + m_runtime_session_began = true; } - void Profiler::appendProfileData(ProfileResult&& result) + void Profiler::AppendProfileData(ProfileResult&& result) { std::lock_guard lock(_mutex); - auto it = _profile_data.find(result.name); - if(it != _profile_data.end()) + auto it = m_profile_data.find(result.name); + if(it != m_profile_data.end()) { result.elapsed_time = (result.elapsed_time + it->second.second.elapsed_time) / it->second.first; - _profile_data[result.name].first++; - _profile_data[result.name].second = result; + m_profile_data[result.name].first++; + m_profile_data[result.name].second = result; } else - _profile_data[result.name] = std::make_pair(1, result); + m_profile_data[result.name] = std::make_pair(1, result); } - void Profiler::writeProfile(const ProfileResult& result) + void Profiler::WriteProfile(const ProfileResult& result) { std::stringstream json; json << std::setprecision(9) << std::fixed; @@ -56,26 +54,26 @@ namespace mlx json << "\t\"thread id\" : " << result.thread_id << "," << '\n'; json << "\t\"average duration\" : \"" << result.elapsed_time.count() << "ms\"\n"; json << "}"; - _output_stream << json.str(); + m_output_stream << json.str(); } - void Profiler::endRuntimeSession() + void Profiler::EndRuntimeSession() { - std::lock_guard lock(_mutex); - if(!_runtime_session_began) + std::lock_guard lock(m_mutex); + if(!m_runtime_session_began) return; - for(auto& [_, pair] : _profile_data) - writeProfile(pair.second); - writeFooter(); - _output_stream.close(); - _profile_data.clear(); - _runtime_session_began = false; + for(auto& [_, pair] : m_profile_data) + WriteProfile(pair.second); + WriteFooter(); + m_output_stream.close(); + m_profile_data.clear(); + m_runtime_session_began = false; } Profiler::~Profiler() { - if(!_runtime_session_began) + if(!m_runtime_session_began) return; - endRuntimeSession(); + EndRuntimeSession(); } } diff --git a/runtime/Sources/Core/UUID.cpp b/runtime/Sources/Core/UUID.cpp index 744b4c9..96ae62f 100644 --- a/runtime/Sources/Core/UUID.cpp +++ b/runtime/Sources/Core/UUID.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/06 11:26:37 by maldavid #+# #+# */ -/* Updated: 2024/03/25 19:00:36 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 14:09:35 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,6 +20,6 @@ namespace mlx static std::mt19937_64 engine(random_device()); static std::uniform_int_distribution uniform_distribution; - UUID::UUID() : _uuid(uniform_distribution(engine)) {} - UUID::UUID(std::uint64_t uuid) : _uuid(uuid) {} + UUID::UUID() : m_uuid(uniform_distribution(engine)) {} + UUID::UUID(std::uint64_t uuid) : m_uuid(uuid) {} } diff --git a/runtime/Sources/Renderer/Buffers/Buffer.cpp b/runtime/Sources/Renderer/Buffers/Buffer.cpp index 1b704fe..6f6455f 100644 --- a/runtime/Sources/Renderer/Buffers/Buffer.cpp +++ b/runtime/Sources/Renderer/Buffers/Buffer.cpp @@ -1,67 +1,66 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* vk_buffer.cpp :+: :+: :+: */ +/* Buffer.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/08 18:55:57 by maldavid #+# #+# */ -/* Updated: 2024/03/25 19:01:18 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 14:20:13 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ -#include +#include -#include "vk_buffer.h" -#include -#include -#include -#include +#include +#include +#include +#include namespace mlx { - void Buffer::create(Buffer::kind type, VkDeviceSize size, VkBufferUsageFlags usage, const char* name, const void* data) + void Buffer::Create(BufferType type, VkDeviceSize size, VkBufferUsageFlags usage, const char* name, const void* data) { MLX_PROFILE_FUNCTION(); - _usage = usage; - if(type == Buffer::kind::constant || type == Buffer::kind::dynamic_device_local) + m_usage = usage; + if(type == BufferType::Constant || type == BufferType::LowDynamic) { - if(data == nullptr && type == Buffer::kind::constant) + if(data == nullptr && type == BufferType::Constant) { - core::error::report(e_kind::warning, "Vulkan : trying to create constant buffer without data (constant buffers cannot be modified after creation)"); + Warning("Vulkan : trying to create constant buffer without data (constant buffers cannot be modified after creation)"); return; } - _usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + m_usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; } VmaAllocationCreateInfo alloc_info{}; alloc_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT; alloc_info.usage = VMA_MEMORY_USAGE_AUTO; - createBuffer(_usage, alloc_info, size, name); + CreateBuffer(m_usage, alloc_info, size, name); if(data != nullptr) { void* mapped = nullptr; - mapMem(&mapped); + MapMem(&mapped); std::memcpy(mapped, data, size); - unmapMem(); - if(type == Buffer::kind::constant || type == Buffer::kind::dynamic_device_local) - pushToGPU(); + UnmapMem(); + if(type == BufferType::constant || type == BufferType::LowDynamic) + PushToGPU(); } } - void Buffer::destroy() noexcept + void Buffer::Destroy() noexcept { MLX_PROFILE_FUNCTION(); - if(_is_mapped) - unmapMem(); - if(_buffer != VK_NULL_HANDLE) - Render_Core::get().getAllocator().destroyBuffer(_allocation, _buffer); - _buffer = VK_NULL_HANDLE; + if(m_is_mapped) + UnmapMem(); + if(m_buffer != VK_NULL_HANDLE) + RenderCore::Get().GetAllocator().DestroyBuffer(m_allocation, m_buffer); + m_buffer = VK_NULL_HANDLE; } - void Buffer::createBuffer(VkBufferUsageFlags usage, VmaAllocationCreateInfo info, VkDeviceSize size, [[maybe_unused]] const char* name) + void Buffer::CreateBuffer(VkBufferUsageFlags usage, VmaAllocationCreateInfo info, VkDeviceSize size, [[maybe_unused]] const char* name) { MLX_PROFILE_FUNCTION(); VkBufferCreateInfo bufferInfo{}; @@ -71,97 +70,81 @@ namespace mlx bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; #ifdef DEBUG - _name = name; - std::string alloc_name = _name; + m_name = name; + std::string alloc_name = m_name; if(usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT) alloc_name.append("_index_buffer"); else if(usage & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) alloc_name.append("_vertex_buffer"); else if(!(usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)) alloc_name.append("_buffer"); - _allocation = Render_Core::get().getAllocator().createBuffer(&bufferInfo, &info, _buffer, alloc_name.c_str()); + m_allocation = RenderCore::Get().GetAllocator().CreateBuffer(&bufferInfo, &info, m_buffer, alloc_name.c_str()); #else - _allocation = Render_Core::get().getAllocator().createBuffer(&bufferInfo, &info, _buffer, nullptr); + m_allocation = RenderCore::Get().GetAllocator().CreateBuffer(&bufferInfo, &info, m_buffer, nullptr); #endif - _size = size; + m_size = size; } - bool Buffer::copyFromBuffer(const Buffer& buffer) noexcept + bool Buffer::CopyFromBuffer(const Buffer& buffer) noexcept { MLX_PROFILE_FUNCTION(); - if(!(_usage & VK_BUFFER_USAGE_TRANSFER_DST_BIT)) + if(!(m_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"); + 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)) + if(!(buffer.m_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"); + Error("Vulkan : buffer cannot be the source of a copy because it does not have the correct usage flag"); return false; } - CmdBuffer& cmd = Render_Core::get().getSingleTimeCmdBuffer(); - cmd.beginRecord(); + CmdBuffer& cmd = RenderCore::Get().GetSingleTimeCmdBuffer(); + cmd.BeginRecord(); - cmd.copyBuffer(*this, const_cast(buffer)); + cmd.CopyBuffer(*this, const_cast(buffer)); - cmd.endRecord(); - cmd.submitIdle(); + cmd.EndRecord(); + cmd.SubmitIdle(); return true; } - void Buffer::pushToGPU() noexcept + void Buffer::PushToGPU() noexcept { MLX_PROFILE_FUNCTION(); VmaAllocationCreateInfo alloc_info{}; alloc_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; - Buffer newBuffer; - newBuffer._usage = (_usage & 0xFFFFFFFC) | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + Buffer new_buffer; + new_buffer.m_usage = (m_usage & 0xFFFFFFFC) | VK_BUFFER_USAGE_TRANSFER_DST_BIT; #ifdef DEBUG - std::string new_name = _name + "_GPU"; - newBuffer.createBuffer(newBuffer._usage, alloc_info, _size, new_name.c_str()); + std::string new_name = m_name + "_GPU"; + new_buffer.CreateBuffer(new_buffer.m_usage, alloc_info, m_size, new_name.c_str()); #else - newBuffer.createBuffer(newBuffer._usage, alloc_info, _size, nullptr); + new_buffer.CreateBuffer(new_buffer.m_usage, alloc_info, m_size, nullptr); #endif - if(newBuffer.copyFromBuffer(*this)) // if the copy succeded we swap the buffers, otherwise the new one is deleted - this->swap(newBuffer); - newBuffer.destroy(); + if(new_buffer.CopyFromBuffer(*this)) // if the copy succeded we swap the buffers, otherwise the new one is deleted + this->Swap(new_buffer); + new_buffer.Destroy(); // destroying the old buffer as they have been swapped } - void Buffer::swap(Buffer& buffer) noexcept + void Buffer::Swap(Buffer& buffer) noexcept { - VkBuffer temp_b = _buffer; - _buffer = buffer._buffer; - buffer._buffer = temp_b; - - VmaAllocation temp_a = buffer._allocation; - buffer._allocation = _allocation; - _allocation = temp_a; - - VkDeviceSize temp_size = buffer._size; - buffer._size = _size; - _size = temp_size; - - VkDeviceSize temp_offset = buffer._offset; - buffer._offset = _offset; - _offset = temp_offset; - - VkBufferUsageFlags temp_u = _usage; - _usage = buffer._usage; - buffer._usage = temp_u; - + std::swap(m_buffer, buffer.m_buffer); + std::swap(m_allocation, buffer.m_allocation); + std::swap(m_size, buffer.m_size); + std::swap(m_offset, buffer.m_offset); #ifdef DEBUG - std::string temp_n = _name; - _name = buffer._name; - buffer._name = temp_n; + std::swap(m_name, buffer.m_name); #endif + std::swap(m_usage, buffer.m_usage); + std::swap(m_is_mapped, buffer.m_is_mapped); } - void Buffer::flush(VkDeviceSize size, VkDeviceSize offset) + void Buffer::Flush(VkDeviceSize size, VkDeviceSize offset) { - Render_Core::get().getAllocator().flush(_allocation, size, offset); + RenderCore::Get().GetAllocator().Flush(m_allocation, size, offset); } } diff --git a/runtime/Sources/Renderer/Buffers/UniformBuffer.cpp b/runtime/Sources/Renderer/Buffers/UniformBuffer.cpp index 52cb3df..0359c03 100644 --- a/runtime/Sources/Renderer/Buffers/UniformBuffer.cpp +++ b/runtime/Sources/Renderer/Buffers/UniformBuffer.cpp @@ -1,79 +1,78 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* vk_ubo.cpp :+: :+: :+: */ +/* UniformBuffer.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/06 18:45:52 by maldavid #+# #+# */ -/* Updated: 2024/03/25 17:48:07 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 14:25:17 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ -#include +#include -#include "vk_ubo.h" -#include -#include +#include +#include namespace mlx { - void UBO::create(Renderer* renderer, std::uint32_t size, [[maybe_unused]] const char* name) + void UniformBuffer::create(NonOwningPtr renderer, std::uint32_t size, [[maybe_unused]] const char* name) { MLX_PROFILE_FUNCTION(); - _renderer = renderer; + p_renderer = renderer; for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { #ifdef DEBUG std::string name_frame = name; name_frame.append(std::to_string(i)); - _buffers[i].create(Buffer::kind::uniform, size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, name_frame.c_str()); + m_buffers[i].create(BufferType::HighDynamic, size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, name_frame.c_str()); #else - _buffers[i].create(Buffer::kind::uniform, size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, nullptr); + _buffers[i].Create(BufferType::HighDynamic, size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, nullptr); #endif - _buffers[i].mapMem(&_maps[i]); - if(_maps[i] == nullptr) - core::error::report(e_kind::fatal_error, "Vulkan : unable to map a uniform buffer"); + m_buffers[i].MapMem(&_maps[i]); + if(m_maps[i] == nullptr) + FatalError("Vulkan : unable to map a uniform buffer"); } } - void UBO::setData(std::uint32_t size, const void* data) + void UniformBuffer::SetData(std::uint32_t size, const void* data) { MLX_PROFILE_FUNCTION(); - std::memcpy(_maps[_renderer->getActiveImageIndex()], data, static_cast(size)); + std::memcpy(m_maps[p_renderer->GetActiveImageIndex()], data, static_cast(size)); } - void UBO::setDynamicData(std::uint32_t size, const void* data) + void UniformBuffer::SetDynamicData(std::uint32_t size, const void* data) { MLX_PROFILE_FUNCTION(); - std::memcpy(_maps[_renderer->getActiveImageIndex()], data, static_cast(size)); - _buffers[_renderer->getActiveImageIndex()].flush(); + std::memcpy(m_maps[p_renderer->GetActiveImageIndex()], data, static_cast(size)); + m_buffers[p_renderer->GetActiveImageIndex()].Flush(); } - unsigned int UBO::getSize() noexcept + unsigned int UniformBuffer::GetSize() noexcept { - return _buffers[_renderer->getActiveImageIndex()].getSize(); + return m_buffers[p_renderer->GetActiveImageIndex()].GetSize(); } - unsigned int UBO::getOffset() noexcept + unsigned int UniformBuffer::GetOffset() noexcept { - return _buffers[_renderer->getActiveImageIndex()].getOffset(); + return m_buffers[p_renderer->GetActiveImageIndex()].GetOffset(); } - VkBuffer& UBO::operator()() noexcept + VkBuffer& UniformBuffer::operator()() noexcept { - return _buffers[_renderer->getActiveImageIndex()].get(); + return m_buffers[p_renderer->GetActiveImageIndex()].Get(); } - VkBuffer& UBO::get() noexcept + VkBuffer& UniformBuffer::Get() noexcept { - return _buffers[_renderer->getActiveImageIndex()].get(); + return m_buffers[p_renderer->GetActiveImageIndex()].Get(); } - void UBO::destroy() noexcept + void UniformBuffer::Destroy() noexcept { for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) - _buffers[i].destroy(); + m_buffers[i].Destroy(); } } diff --git a/runtime/Sources/Renderer/Buffers/VertexBuffer.cpp b/runtime/Sources/Renderer/Buffers/VertexBuffer.cpp index 418ffeb..41afa98 100644 --- a/runtime/Sources/Renderer/Buffers/VertexBuffer.cpp +++ b/runtime/Sources/Renderer/Buffers/VertexBuffer.cpp @@ -1,56 +1,56 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* vk_vbo.cpp :+: :+: :+: */ +/* VertexBuffer.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/06 18:28:08 by maldavid #+# #+# */ -/* Updated: 2024/03/25 19:01:25 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 14:48:15 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ -#include +#include -#include "vk_vbo.h" +#include namespace mlx { - void VBO::setData(std::uint32_t size, const void* data) + void RAMVertexBuffer::SetData(std::uint32_t size, const void* data) { - if(size > getSize()) + 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()); + Error("Vulkan : trying to store to much data in a vertex buffer (% bytes in % bytes)", size, GetSize()); return; } if(data == nullptr) - core::error::report(e_kind::warning, "Vulkan : mapping null data in a vertex buffer"); + Warning("Vulkan : mapping null data in a vertex buffer"); void* temp = nullptr; - mapMem(&temp); + MapMem(&temp); std::memcpy(temp, data, static_cast(size)); - unmapMem(); + UnmapMem(); } - void D_VBO::setData(std::uint32_t size, const void* data) + void DeviceVertexBuffer::SetData(std::uint32_t size, const void* data) { - if(size > getSize()) + 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()); + Error("Vulkan : trying to store to much data in a vertex buffer (% bytes in % bytes)", size, GetSize()); return; } if(data == nullptr) - core::error::report(e_kind::warning, "Vulkan : mapping null data in a vertex buffer"); + 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); + tmp_buf.Create(BufferType::HighDynamic, 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); + tmp_buf.Create(BufferType::HighDynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, nullptr, data); #endif - copyFromBuffer(tmp_buf); - tmp_buf.destroy(); + CopyFromBuffer(tmp_buf); + tmp_buf.Destroy(); } } diff --git a/runtime/Sources/Renderer/Command/CommandBuffer.cpp b/runtime/Sources/Renderer/Command/CommandBuffer.cpp index a2d0a25..6574682 100644 --- a/runtime/Sources/Renderer/Command/CommandBuffer.cpp +++ b/runtime/Sources/Renderer/Command/CommandBuffer.cpp @@ -1,33 +1,32 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* vk_cmd_buffer.cpp :+: :+: :+: */ +/* CommandBuffer.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/06 18:26:06 by maldavid #+# #+# */ -/* Updated: 2024/03/25 19:01:37 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 18:02:20 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ -#include +#include -#include "vk_cmd_buffer.h" -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include namespace mlx { - bool vector_push_back_if_not_found(std::vector& vector, CmdResource* res) + bool VectorPushBackIfNotFound(std::vector>& vector, NonOwningPtr res) { - auto it = std::find_if(vector.begin(), vector.end(), [=](const CmdResource* vres) + auto it = std::find_if(vector.begin(), vector.end(), [=](const NonOwningPtr vres) { - return vres->getUUID() == res->getUUID(); + return vres->GetUUID() == res->GetUUID(); }); if(it == vector.end()) @@ -38,113 +37,113 @@ namespace mlx return false; } - void CmdBuffer::init(kind type, CmdManager* manager) + void CmommanBuffer::Init(CommandBufferType type, NonOwningPtr manager) { - init(type, &manager->getCmdPool()); + Init(type, &manager->GetCmdPool()); } - void CmdBuffer::init(kind type, CmdPool* pool) + void CommandBuffer::Init(CommandBufferType type, NonOwningPtr pool) { MLX_PROFILE_FUNCTION(); - _type = type; - _pool = pool; + m_type = type; + m_pool = pool; - VkCommandBufferAllocateInfo allocInfo{}; - allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - allocInfo.commandPool = pool->get(); - allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - allocInfo.commandBufferCount = 1; + VkCommandBufferAllocateInfo alloc_info{}; + alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + alloc_info.commandPool = pool->get(); + alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + alloc_info.commandBufferCount = 1; - VkResult res = vkAllocateCommandBuffers(Render_Core::get().getDevice().get(), &allocInfo, &_cmd_buffer); + VkResult res = vkAllocateCommandBuffers(RenderCore::Get().getDevice().get(), &allocInfo, &_cmd_buffer); if(res != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Vulkan : failed to allocate command buffer, %s", RCore::verbaliseResultVk(res)); + FatalError("Vulkan : failed to allocate command buffer, %s", RCore::verbaliseResultVk(res)); #ifdef DEBUG - core::error::report(e_kind::message, "Vulkan : created new command buffer"); + Message("Vulkan : created new command buffer"); #endif - _fence.init(); - _state = state::idle; + m_fence.init(); + state = CommandBufferState::Idle; } - void CmdBuffer::beginRecord(VkCommandBufferUsageFlags usage) + void CommandBuffer::BeginRecord(VkCommandBufferUsageFlags usage) { MLX_PROFILE_FUNCTION(); - if(!isInit()) - core::error::report(e_kind::fatal_error, "Vulkan : begenning record on un uninit command buffer"); - if(_state == state::recording) + if(!IsInit()) + FatalError("Vulkan : begenning record on un uninit command buffer"); + if(m_state == CommandBufferState::Recording) return; - VkCommandBufferBeginInfo beginInfo{}; - beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - beginInfo.flags = usage; - if(vkBeginCommandBuffer(_cmd_buffer, &beginInfo) != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Vulkan : failed to begin recording command buffer"); + VkCommandBufferBeginInfo begin_info{}; + begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + begin_info.flags = usage; + if(vkBeginCommandBuffer(m_cmd_buffer, &begin_info) != VK_SUCCESS) + FatalError("Vulkan : failed to begin recording command buffer"); - _state = state::recording; + m_state = CommandBufferState::Recording; } - void CmdBuffer::bindVertexBuffer(Buffer& buffer) noexcept + void CommandBuffer::BindVertexBuffer(Buffer& buffer) noexcept { MLX_PROFILE_FUNCTION(); - if(!isRecording()) + if(!IsRecording()) { - core::error::report(e_kind::warning, "Vulkan : trying to bind a vertex buffer to a non recording command buffer"); + Warning("Vulkan : trying to bind a vertex buffer to a non recording command buffer"); return; } - VkDeviceSize offset[] = { buffer.getOffset() }; - vkCmdBindVertexBuffers(_cmd_buffer, 0, 1, &buffer.get(), offset); + VkDeviceSize offset[] = { buffer.GetOffset() }; + vkCmdBindVertexBuffers(m_cmd_buffer, 0, 1, &buffer.Get(), offset); - buffer.recordedInCmdBuffer(); - vector_push_back_if_not_found(_cmd_resources, &buffer); + buffer.RecordedInCommandBuffer(); + VectorPushBackIfNotFound(m_cmd_resources, &buffer); } - void CmdBuffer::bindIndexBuffer(Buffer& buffer) noexcept + void CommandBuffer::NindIndexBuffer(Buffer& buffer) noexcept { MLX_PROFILE_FUNCTION(); - if(!isRecording()) + if(!IsRecording()) { - core::error::report(e_kind::warning, "Vulkan : trying to bind a index buffer to a non recording command buffer"); + Warning("Vulkan : trying to bind a index buffer to a non recording command buffer"); return; } - vkCmdBindIndexBuffer(_cmd_buffer, buffer.get(), buffer.getOffset(), VK_INDEX_TYPE_UINT16); + vkCmdBindIndexBuffer(m_cmd_buffer, buffer.Get(), buffer.GetOffset(), VK_INDEX_TYPE_UINT16); - buffer.recordedInCmdBuffer(); - vector_push_back_if_not_found(_cmd_resources, &buffer); + buffer.RecordedInCommandBuffer(); + VectorPushBackIfNotFound(m_cmd_resources, &buffer); } - void CmdBuffer::copyBuffer(Buffer& dst, Buffer& src) noexcept + void CommandBuffer::CopyBuffer(Buffer& dst, Buffer& src) noexcept { MLX_PROFILE_FUNCTION(); - if(!isRecording()) + if(!IsRecording()) { - core::error::report(e_kind::warning, "Vulkan : trying to do a buffer to buffer copy in a non recording command buffer"); + Warning("Vulkan : trying to do a buffer to buffer copy in a non recording command buffer"); return; } - preTransferBarrier(); + PreTransferBarrier(); - VkBufferCopy copyRegion{}; - copyRegion.size = src.getSize(); - vkCmdCopyBuffer(_cmd_buffer, src.get(), dst.get(), 1, ©Region); + VkBufferCopy copy_region{}; + copy_region.size = src.GetSize(); + vkCmdCopyBuffer(m_cmd_buffer, src.Get(), dst.Get(), 1, ©_region); - postTransferBarrier(); + PostTransferBarrier(); - dst.recordedInCmdBuffer(); - src.recordedInCmdBuffer(); - vector_push_back_if_not_found(_cmd_resources, &dst); - vector_push_back_if_not_found(_cmd_resources, &src); + dst.RecordedInCommandBuffer(); + src.RecordedInCommandBuffer(); + VectorPushBackIfNotFound(m_cmd_resources, &dst); + VectorPushBackIfNotFound(m_cmd_resources, &src); } - void CmdBuffer::copyBufferToImage(Buffer& buffer, Image& image) noexcept + void CommandBuffer::CopyBufferToImage(Buffer& buffer, Image& image) noexcept { MLX_PROFILE_FUNCTION(); - if(!isRecording()) + if(!IsRecording()) { - core::error::report(e_kind::warning, "Vulkan : trying to do a buffer to image copy in a non recording command buffer"); + Warning("Vulkan : trying to do a buffer to image copy in a non recording command buffer"); return; } - - preTransferBarrier(); + + PreTransferBarrier(); VkBufferImageCopy region{}; region.bufferOffset = 0; @@ -155,28 +154,28 @@ namespace mlx region.imageSubresource.baseArrayLayer = 0; region.imageSubresource.layerCount = 1; region.imageOffset = { 0, 0, 0 }; - region.imageExtent = { image.getWidth(), image.getHeight(), 1 }; + region.imageExtent = { image.GetWidth(), image.GetHeight(), 1 }; - vkCmdCopyBufferToImage(_cmd_buffer, buffer.get(), image.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + vkCmdCopyBufferToImage(m_cmd_buffer, buffer.Get(), image.Get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); - postTransferBarrier(); + PostTransferBarrier(); - image.recordedInCmdBuffer(); - buffer.recordedInCmdBuffer(); - vector_push_back_if_not_found(_cmd_resources, &image); - vector_push_back_if_not_found(_cmd_resources, &buffer); + image.RecordedInCommandBuffer(); + buffer.RecordedInCommandBuffer(); + VectorPushBackIfNotFound(m_cmd_resources, &image); + VectorPushBackIfNotFound(m_cmd_resources, &buffer); } - void CmdBuffer::copyImagetoBuffer(Image& image, Buffer& buffer) noexcept + void CommandBuffer::CopyImagetoBuffer(Image& image, Buffer& buffer) noexcept { MLX_PROFILE_FUNCTION(); - if(!isRecording()) + if(!IsRecording()) { - core::error::report(e_kind::warning, "Vulkan : trying to do an image to buffer copy in a non recording command buffer"); + Warning("Vulkan : trying to do an image to buffer copy in a non recording command buffer"); return; } - preTransferBarrier(); + PreTransferBarrier(); VkBufferImageCopy region{}; region.bufferOffset = 0; @@ -187,184 +186,180 @@ namespace mlx region.imageSubresource.baseArrayLayer = 0; region.imageSubresource.layerCount = 1; region.imageOffset = { 0, 0, 0 }; - region.imageExtent = { image.getWidth(), image.getHeight(), 1 }; + region.imageExtent = { image.GetWidth(), image.GetHeight(), 1 }; - vkCmdCopyImageToBuffer(_cmd_buffer, image.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer.get(), 1, ®ion); + vkCmdCopyImageToBuffer(m_cmd_buffer, image.Get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer.Get(), 1, ®ion); - postTransferBarrier(); + PostTransferBarrier(); - image.recordedInCmdBuffer(); - buffer.recordedInCmdBuffer(); - vector_push_back_if_not_found(_cmd_resources, &buffer); - vector_push_back_if_not_found(_cmd_resources, &image); + image.RecordedInCommandBuffer(); + buffer.RecordedInCommandBuffer(); + VectorPushBackIfNotFound(m_cmd_resources, &buffer); + VectorPushBackIfNotFound(m_cmd_resources, &image); } - void CmdBuffer::transitionImageLayout(Image& image, VkImageLayout new_layout) noexcept + void CommandBuffer::TransitionImageLayout(Image& image, VkImageLayout new_layout) noexcept { MLX_PROFILE_FUNCTION(); - if(!isRecording()) + if(!IsRecording()) { - core::error::report(e_kind::warning, "Vulkan : trying to do an image layout transition in a non recording command buffer"); + Warning("Vulkan : trying to do an image layout transition in a non recording command buffer"); return; } VkImageMemoryBarrier barrier{}; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - barrier.oldLayout = image.getLayout(); + barrier.oldLayout = image.GetLayout(); barrier.newLayout = new_layout; barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - barrier.image = image.get(); - barrier.subresourceRange.aspectMask = isDepthFormat(image.getFormat()) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; + barrier.image = image.Get(); + barrier.subresourceRange.aspectMask = IsDepthFormat(image.GetFormat()) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT; barrier.subresourceRange.baseMipLevel = 0; barrier.subresourceRange.levelCount = 1; barrier.subresourceRange.baseArrayLayer = 0; barrier.subresourceRange.layerCount = 1; - barrier.srcAccessMask = layoutToAccessMask(image.getLayout(), false); - barrier.dstAccessMask = layoutToAccessMask(new_layout, true); - if(isStencilFormat(image.getFormat())) + barrier.srcAccessMask = LayoutToAccessMask(image.GetLayout(), false); + barrier.dstAccessMask = LayoutToAccessMask(new_layout, true); + if(IsStencilFormat(image.GetFormat())) barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; - VkPipelineStageFlags sourceStage = 0; + VkPipelineStageFlags source_stage = 0; if(barrier.oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) - sourceStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + source_stage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; else if(barrier.srcAccessMask != 0) - sourceStage = RCore::accessFlagsToPipelineStage(barrier.srcAccessMask, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT); + source_stage = AccessFlagsToPipelineStage(barrier.srcAccessMask, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT); else - sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + source_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - VkPipelineStageFlags destinationStage = 0; + VkPipelineStageFlags destination_stage = 0; if(barrier.newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) - destinationStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + destination_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; else if(barrier.dstAccessMask != 0) - destinationStage = RCore::accessFlagsToPipelineStage(barrier.dstAccessMask, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT); + destination_stage = AccessFlagsToPipelineStage(barrier.dstAccessMask, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT); else - destinationStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + destination_stage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - vkCmdPipelineBarrier(_cmd_buffer, sourceStage, destinationStage, 0, 0, nullptr, 0, nullptr, 1, &barrier); + vkCmdPipelineBarrier(m_cmd_buffer, source_stage, destination_stage, 0, 0, nullptr, 0, nullptr, 1, &barrier); - image.recordedInCmdBuffer(); - vector_push_back_if_not_found(_cmd_resources, &image); + image.RecordedInCommandBuffer(); + VectorPushBackIfNotFound(m_cmd_resources, &image); } - void CmdBuffer::endRecord() + void CommandBuffer::EndRecord() { MLX_PROFILE_FUNCTION(); - if(!isInit()) - core::error::report(e_kind::fatal_error, "Vulkan : ending record on un uninit command buffer"); - if(_state != state::recording) + if(!IsInit()) + FatalError("Vulkan : ending record on un uninit command buffer"); + if(m_state != CommandBufferState::Recording) return; - if(vkEndCommandBuffer(_cmd_buffer) != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Vulkan : failed to end recording command buffer"); + if(vkEndCommandBuffer(m_cmd_buffer) != VK_SUCCESS) + FatalError("Vulkan : failed to end recording command buffer"); - _state = state::idle; + m_state = CommandBufferState::Idle; } - void CmdBuffer::submitIdle(bool shouldWaitForExecution) noexcept + void CommandBuffer::SubmitIdle(bool should_wait_for_execution) noexcept { MLX_PROFILE_FUNCTION(); - if(_type != kind::single_time) + if(m_type != CommandBufferType::SingleTime) { - core::error::report(e_kind::error, "Vulkan : try to perform an idle submit on a command buffer that is not single-time, this is not allowed"); + Error("Vulkan : try to perform an idle submit on a command buffer that is not single-time, this is not allowed"); return; } - _fence.reset(); + m_fence.Reset(); - VkSubmitInfo submitInfo{}; - submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &_cmd_buffer; + VkSubmitInfo submit_info{}; + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_info.commandBufferCount = 1; + submit_info.pCommandBuffers = &m_cmd_buffer; - VkResult res = vkQueueSubmit(Render_Core::get().getQueue().getGraphic(), 1, &submitInfo, _fence.get()); + VkResult res = vkQueueSubmit(RenderCore::Get().GetQueue().GetGraphic(), 1, &submit_info, m_fence.Get()); if(res != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Vulkan error : failed to submit a single time command buffer, %s", RCore::verbaliseResultVk(res)); - _state = state::submitted; + FatalError("Vulkan error : failed to submit a single time command buffer, %", VerbaliseVkResult(res)); + m_state = CommandBufferState::Submitted; - if(shouldWaitForExecution) - waitForExecution(); + if(should_wait_for_execution) + WaitForExecution(); } - void CmdBuffer::submit(Semaphore* semaphores) noexcept + void CommandBuffer::Submit(NonOwningPtr signal, NonOwningPtr wait) noexcept { MLX_PROFILE_FUNCTION(); - std::array signalSemaphores; - std::array waitSemaphores; + std::array signal_semaphores; + std::array wait_semaphores; - if(semaphores != nullptr) - { - signalSemaphores[0] = semaphores->getRenderImageSemaphore(); - waitSemaphores[0] = semaphores->getImageSemaphore(); - } - else - { - signalSemaphores[0] = VK_NULL_HANDLE; - waitSemaphores[0] = VK_NULL_HANDLE; - } - VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; + signal_semaphores[0] = (signal ? signal->Get() : VK_NULL_HANDLE); - _fence.reset(); + wait_semaphores[0] = (wait ? wait->Get() : VK_NULL_HANDLE); + VkPipelineStageFlags wait_stages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; - VkSubmitInfo submitInfo{}; - submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.waitSemaphoreCount = (semaphores == nullptr ? 0 : waitSemaphores.size()); - submitInfo.pWaitSemaphores = waitSemaphores.data(); - submitInfo.pWaitDstStageMask = waitStages; - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &_cmd_buffer; - submitInfo.signalSemaphoreCount = (semaphores == nullptr ? 0 : signalSemaphores.size()); - submitInfo.pSignalSemaphores = signalSemaphores.data(); + m_fence.Reset(); - VkResult res = vkQueueSubmit(Render_Core::get().getQueue().getGraphic(), 1, &submitInfo, _fence.get()); + VkSubmitInfo submit_info{}; + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_info.waitSemaphoreCount = (!wait ? 0 : wait_semaphores.size()); + submit_info.pWaitSemaphores = wait_semaphores.data(); + submit_info.pWaitDstStageMask = wait_stages; + submit_info.commandBufferCount = 1; + submit_info.pCommandBuffers = &m_cmd_buffer; + submit_info.signalSemaphoreCount = (!signal ? 0 : signal_semaphores.size()); + submit_info.pSignalSemaphores = signal_semaphores.data(); + + VkResult res = vkQueueSubmit(RenderCore::Get().GetQueue().GetGraphic(), 1, &submit_info, m_fence.get()); if(res != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Vulkan error : failed to submit draw command buffer, %s", RCore::verbaliseResultVk(res)); - _state = state::submitted; + FatalError("Vulkan error : failed to submit draw command buffer, %", VerbaliseVkResult(res)); + m_state = CommandBufferState::Submitted; } - void CmdBuffer::updateSubmitState() noexcept + void CommandBuffer::UpdateSubmitState() noexcept { MLX_PROFILE_FUNCTION(); - if(!_fence.isReady()) + if(!m_fence.IsReady()) return; - for(CmdResource* res : _cmd_resources) - res->removedFromCmdBuffer(); - _cmd_resources.clear(); - _state = state::ready; + for(NonOwningPtr res : m_cmd_resources) + { + if(res) + res->RemovedFromCommandBuffer(); + } + m_cmd_resources.clear(); + m_state = CommandBufferState::Ready; } - void CmdBuffer::preTransferBarrier() noexcept + void CommandBuffer::PreTransferBarrier() noexcept { MLX_PROFILE_FUNCTION(); - VkMemoryBarrier memoryBarrier{}; - memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; - memoryBarrier.pNext = nullptr; - memoryBarrier.srcAccessMask = 0U; - memoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + VkMemoryBarrier memory_barrier{}; + memory_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; + memory_barrier.pNext = nullptr; + memory_barrier.srcAccessMask = 0U; + memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - vkCmdPipelineBarrier(_cmd_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &memoryBarrier, 0, nullptr, 0, nullptr); + vkCmdPipelineBarrier(m_cmd_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1, &memory_barrier, 0, nullptr, 0, nullptr); } - void CmdBuffer::postTransferBarrier() noexcept + void CommandBuffer::PostTransferBarrier() noexcept { MLX_PROFILE_FUNCTION(); - VkMemoryBarrier memoryBarrier{}; - memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; - memoryBarrier.pNext = nullptr; - memoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - memoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_UNIFORM_READ_BIT; + VkMemoryBarrier memory_barrier{}; + memory_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; + memory_barrier.pNext = nullptr; + memory_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_UNIFORM_READ_BIT; - vkCmdPipelineBarrier(_cmd_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 1, &memoryBarrier, 0, nullptr, 0, nullptr); + vkCmdPipelineBarrier(m_cmd_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 1, &memory_barrier, 0, nullptr, 0, nullptr); } - void CmdBuffer::destroy() noexcept + void CommandBuffer::Destroy() noexcept { MLX_PROFILE_FUNCTION(); - _fence.destroy(); - _cmd_buffer = VK_NULL_HANDLE; - _state = state::uninit; + m_fence.Destroy(); + m_cmd_buffer = VK_NULL_HANDLE; + m_state = CommandBufferState::Uninit; #ifdef DEBUG - core::error::report(e_kind::message, "Vulkan : destroyed command buffer"); + Message("Vulkan : destroyed command buffer"); #endif } } diff --git a/runtime/Sources/Renderer/Command/CommandManager.cpp b/runtime/Sources/Renderer/Command/CommandManager.cpp index 9de7d82..df6fab9 100644 --- a/runtime/Sources/Renderer/Command/CommandManager.cpp +++ b/runtime/Sources/Renderer/Command/CommandManager.cpp @@ -1,42 +1,42 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* cmd_manager.cpp :+: :+: :+: */ +/* CommandManager.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/02 17:50:52 by maldavid #+# #+# */ -/* Updated: 2024/03/25 19:01:30 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 14:55:04 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ -#include +#include -#include +#include namespace mlx { - void CmdManager::init() noexcept + void CommandManager::Init() noexcept { - _cmd_pool.init(); + m_cmd_pool.Init(); for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) - _cmd_buffers[i].init(CmdBuffer::kind::long_time, this); + m_cmd_buffers[i].Init(CommandBufferType::LongTime, this); } - void CmdManager::beginRecord(int active_image_index) + void CommandManager::BeginRecord(int active_image_index) { - _cmd_buffers[active_image_index].beginRecord(); + m_cmd_buffers[active_image_index].BeginRecord(); } - void CmdManager::endRecord(int active_image_index) + void CommandManager::EndRecord(int active_image_index) { - _cmd_buffers[active_image_index].endRecord(); + m_cmd_buffers[active_image_index].EndRecord(); } - void CmdManager::destroy() noexcept + void CommandManager::Destroy() noexcept { for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) - _cmd_buffers[i].destroy(); - _cmd_pool.destroy(); + m_cmd_buffers[i].Destroy(); + m_cmd_pool.Destroy(); } } diff --git a/runtime/Sources/Renderer/Command/CommandPool.cpp b/runtime/Sources/Renderer/Command/CommandPool.cpp index fbce122..af576a7 100644 --- a/runtime/Sources/Renderer/Command/CommandPool.cpp +++ b/runtime/Sources/Renderer/Command/CommandPool.cpp @@ -1,37 +1,37 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* vk_cmd_pool.cpp :+: :+: :+: */ +/* CommandPool.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/06 18:24:33 by maldavid #+# #+# */ -/* Updated: 2024/03/25 19:01:41 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 14:57:15 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ -#include +#include -#include "vk_cmd_pool.h" -#include +#include +#include namespace mlx { - void CmdPool::init() + void CommandPool::Init() { - VkCommandPoolCreateInfo poolInfo{}; - poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - poolInfo.queueFamilyIndex = Render_Core::get().getQueue().getFamilies().graphics_family.value(); + VkCommandPoolCreateInfo pool_info{}; + pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + pool_info.queueFamilyIndex = RenderCore::Get().GetQueue().GetFamilies().graphics_family.value(); - VkResult res = vkCreateCommandPool(Render_Core::get().getDevice().get(), &poolInfo, nullptr, &_cmd_pool); + VkResult res = vkCreateCommandPool(RenderCore::Get().GetDevice().Get(), &pool_info, nullptr, &m_cmd_pool); if(res != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Vulkan : failed to create command pool, %s", RCore::verbaliseResultVk(res)); + FatalError("Vulkan : failed to create command pool, %", VerbaliseVkResult(res)); } - void CmdPool::destroy() noexcept + void CommandPool::Destroy() noexcept { - vkDestroyCommandPool(Render_Core::get().getDevice().get(), _cmd_pool, nullptr); - _cmd_pool = VK_NULL_HANDLE; + vkDestroyCommandPool(RenderCore::Get().GetDevice().Get(), m_cmd_pool, nullptr); + m_cmd_pool = VK_NULL_HANDLE; } } diff --git a/runtime/Sources/Renderer/Command/SingleTimeCommandManager.cpp b/runtime/Sources/Renderer/Command/SingleTimeCommandManager.cpp index 7bc96f1..b9fdae4 100644 --- a/runtime/Sources/Renderer/Command/SingleTimeCommandManager.cpp +++ b/runtime/Sources/Renderer/Command/SingleTimeCommandManager.cpp @@ -1,64 +1,64 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* single_time_cmd_manager.cpp :+: :+: :+: */ +/* SingleTimeCommandManager.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/12/15 19:57:49 by maldavid #+# #+# */ -/* Updated: 2024/03/25 19:01:33 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 15:05:19 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ -#include +#include -#include -#include +#include +#include namespace mlx { - void SingleTimeCmdManager::init() noexcept + void SingleTimeCmdManager::Init() noexcept { - _pool.init(); + m_pool.init(); for(int i = 0; i < BASE_POOL_SIZE; i++) { - _buffers.emplace_back(); - _buffers.back().init(CmdBuffer::kind::single_time, &_pool); + m_buffers.emplace_back(); + m_buffers.back().Init(CommandBufferType::SingleTime, &m_pool); } } - CmdBuffer& SingleTimeCmdManager::getCmdBuffer() noexcept + CommandBuffer& SingleTimeCmdManager::GetCmdBuffer() noexcept { - for(CmdBuffer& buf : _buffers) + for(CmdBuffer& buf : m_buffers) { - if(buf.isReadyToBeUsed()) + if(buf.IsReadyToBeUsed()) { buf.reset(); return buf; } } - _buffers.emplace_back().init(CmdBuffer::kind::single_time, &_pool); - return _buffers.back(); + m_buffers.emplace_back().Init(CommandBufferType::SingleTime, &m_pool); + return m_buffers.back(); } - void SingleTimeCmdManager::updateSingleTimesCmdBuffersSubmitState() noexcept + void SingleTimeCmdManager::UpdateSingleTimesCmdBuffersSubmitState() noexcept { - for(CmdBuffer& cmd : _buffers) - cmd.updateSubmitState(); + for(CmdBuffer& cmd : m_buffers) + cmd.UpdateSubmitState(); } - void SingleTimeCmdManager::waitForAllExecutions() noexcept + void SingleTimeCmdManager::WaitForAllExecutions() noexcept { - for(CmdBuffer& cmd : _buffers) - cmd.waitForExecution(); + for(CmdBuffer& cmd : m_buffers) + cmd.WaitForExecution(); } - void SingleTimeCmdManager::destroy() noexcept + void SingleTimeCmdManager::Destroy() noexcept { - std::for_each(_buffers.begin(), _buffers.end(), [](CmdBuffer& buf) + std::for_each(m_buffers.begin(), m_buffers.end(), [](CommandBuffer& buf) { - buf.destroy(); + buf.Destroy(); }); - _pool.destroy(); + m_pool.Destroy(); } } diff --git a/runtime/Sources/Renderer/Core/Device.cpp b/runtime/Sources/Renderer/Core/Device.cpp index 7ed8850..d26e966 100644 --- a/runtime/Sources/Renderer/Core/Device.cpp +++ b/runtime/Sources/Renderer/Core/Device.cpp @@ -1,105 +1,100 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* vk_device.cpp :+: :+: :+: */ +/* Device.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/08 19:14:29 by maldavid #+# #+# */ -/* Updated: 2024/03/25 22:31:54 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 18:10:08 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ -#include +#include -#include "render_core.h" +#include namespace mlx { - const std::vector deviceExtensions = {VK_KHR_SWAPCHAIN_EXTENSION_NAME}; + const std::vector device_extensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME }; - void Device::init() + void Device::Init() { - pickPhysicalDevice(); + PickPhysicalDevice(); - Queues::QueueFamilyIndices indices = Render_Core::get().getQueue().getFamilies(); + Queues::QueueFamilyIndices indices = RenderCore::Get().GetQueue().GetFamilies(); - std::vector queueCreateInfos; - std::set uniqueQueueFamilies = { indices.graphics_family.value(), indices.present_family.value() }; + std::vector queue_create_infos; + std::set unique_queue_families = { indices.graphics_family.value(), indices.present_family.value() }; - float queuePriority = 1.0f; - for(std::uint32_t queueFamily : uniqueQueueFamilies) + float queue_priority = 1.0f; + for(std::uint32_t queue_family : unique_queue_families) { - VkDeviceQueueCreateInfo queueCreateInfo{}; - queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queueCreateInfo.queueFamilyIndex = queueFamily; - queueCreateInfo.queueCount = 1; - queueCreateInfo.pQueuePriorities = &queuePriority; - queueCreateInfos.push_back(queueCreateInfo); + VkDeviceQueueCreateInfo queue_create_info{}; + queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queue_create_info.queueFamilyIndex = queue_family; + queue_create_info.queueCount = 1; + queue_create_info.pQueuePriorities = &queue_priority; + queue_create_infos.push_back(queue_create_info); } - VkPhysicalDeviceFeatures deviceFeatures{}; + VkPhysicalDeviceFeatures device_features{}; - VkDeviceCreateInfo createInfo{}; - createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - - createInfo.queueCreateInfoCount = static_cast(queueCreateInfos.size()); - createInfo.pQueueCreateInfos = queueCreateInfos.data(); - - createInfo.pEnabledFeatures = &deviceFeatures; - - createInfo.enabledExtensionCount = static_cast(deviceExtensions.size()); - createInfo.ppEnabledExtensionNames = deviceExtensions.data(); - createInfo.enabledLayerCount = 0; + VkDeviceCreateInfo create_info{}; + create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + create_info.queueCreateInfoCount = static_cast(queue_create_infos.size()); + create_info.pQueueCreateInfos = queue_create_infos.data(); + create_info.pEnabledFeatures = &device_features; + create_info.enabledExtensionCount = static_cast(device_extensions.size()); + create_info.ppEnabledExtensionNames = device_extensions.data(); + create_info.enabledLayerCount = 0; VkResult res; - if((res = vkCreateDevice(_physical_device, &createInfo, nullptr, &_device)) != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Vulkan : failed to create logcal device, %s", RCore::verbaliseResultVk(res)); - #ifdef DEBUG - core::error::report(e_kind::message, "Vulkan : created new logical device"); - #endif + if((res = vkCreateDevice(m_physical_device, &create_info, nullptr, &m_device)) != VK_SUCCESS) + FatalError("Vulkan : failed to create logcal device, %", VerbaliseVkResult(res)); + DebugLog("Vulkan : created new logical device"); } - void Device::pickPhysicalDevice() + void Device::PickPhysicalDevice() { - std::uint32_t deviceCount = 0; - vkEnumeratePhysicalDevices(Render_Core::get().getInstance().get(), &deviceCount, nullptr); + std::uint32_t device_count = 0; + vkEnumeratePhysicalDevices(RenderCore::Get().GetInstance().Get(), &device_count, nullptr); - if(deviceCount == 0) - core::error::report(e_kind::fatal_error, "Vulkan : failed to find GPUs with Vulkan support"); + if(device_count == 0) + FatalError("Vulkan : failed to find GPUs with Vulkan support"); - std::vector devices(deviceCount); - vkEnumeratePhysicalDevices(Render_Core::get().getInstance().get(), &deviceCount, devices.data()); + std::vector devices(device_count); + vkEnumeratePhysicalDevices(RenderCore::Get().GetInstance().Get(), &device_count, devices.data()); std::multimap devices_score; for(const auto& device : devices) { - int score = deviceScore(device); + int score = DeviceScore(device); devices_score.insert(std::make_pair(score, device)); } if(devices_score.rbegin()->first > 0) - _physical_device = devices_score.rbegin()->second; + m_physical_device = devices_score.rbegin()->second; else - core::error::report(e_kind::fatal_error, "Vulkan : failed to find a suitable GPU"); + FatalError("Vulkan : failed to find a suitable GPU"); #ifdef DEBUG VkPhysicalDeviceProperties props; - vkGetPhysicalDeviceProperties(_physical_device, &props); - core::error::report(e_kind::message, "Vulkan : picked a physical device, %s", props.deviceName); + vkGetPhysicalDeviceProperties(m_physical_device, &props); + DebugLog("Vulkan : picked a physical device, %s", props.deviceName); #endif - Render_Core::get().getQueue().findQueueFamilies(_physical_device); // update queue indicies to current physical device + RenderCore::Get().GetQueue().FindQueueFamilies(m_physical_device); // update queue indicies to current physical device } - int Device::deviceScore(VkPhysicalDevice device) + int Device::DeviceScore(VkPhysicalDevice device) { - Queues::QueueFamilyIndices indices = Render_Core::get().getQueue().findQueueFamilies(device); - bool extensionsSupported = checkDeviceExtensionSupport(device); + Queues::QueueFamilyIndices indices = RenderCore::Get().GetQueue().FindQueueFamilies(device); + bool extensions_supported = CheckDeviceExtensionSupport(device); VkPhysicalDeviceProperties props; vkGetPhysicalDeviceProperties(device, &props); - if(!indices.isComplete() || !extensionsSupported) + if(!indices.IsComplete() || !extensions_supported) return -1; VkPhysicalDeviceFeatures features; @@ -122,28 +117,26 @@ namespace mlx return score; } - bool Device::checkDeviceExtensionSupport(VkPhysicalDevice device) + bool Device::CheckDeviceExtensionSupport(VkPhysicalDevice device) { - std::uint32_t extensionCount; - vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr); + std::uint32_t extension_count; + vkEnumerateDeviceExtensionProperties(device, nullptr, &extension_count, nullptr); - std::vector availableExtensions(extensionCount); - vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data()); + std::vector available_extensions(extensionCount); + vkEnumerateDeviceExtensionProperties(device, nullptr, &extension_count, available_extensions.data()); - std::set requiredExtensions(deviceExtensions.begin(), deviceExtensions.end()); + std::set required_extensions(device_extensions.begin(), device_extensions.end()); - for(const auto& extension : availableExtensions) - requiredExtensions.erase(extension.extensionName); + for(const auto& extension : available_extensions) + required_extensions.erase(extension.extensionName); - return requiredExtensions.empty(); + return required_extensions.empty(); } - void Device::destroy() noexcept + void Device::Destroy() noexcept { - vkDestroyDevice(_device, nullptr); - _device = VK_NULL_HANDLE; - #ifdef DEBUG - core::error::report(e_kind::message, "Vulkan : destroyed a logical device"); - #endif + vkDestroyDevice(m_device, nullptr); + m_device = VK_NULL_HANDLE; + DebugLog("Vulkan : destroyed a logical device"); } } diff --git a/runtime/Sources/Renderer/Core/Fence.cpp b/runtime/Sources/Renderer/Core/Fence.cpp index db3d8e2..7db2b3d 100644 --- a/runtime/Sources/Renderer/Core/Fence.cpp +++ b/runtime/Sources/Renderer/Core/Fence.cpp @@ -1,58 +1,54 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* vk_fence.cpp :+: :+: :+: */ +/* Fence.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/02 17:53:06 by maldavid #+# #+# */ -/* Updated: 2024/03/25 19:02:14 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 18:13:09 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ -#include +#include -#include -#include +#include +#include namespace mlx { - void Fence::init() + void Fence::Init() { - VkFenceCreateInfo fenceInfo{}; - fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; + VkFenceCreateInfo fence_info{}; + fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fence_info.flags = VK_FENCE_CREATE_SIGNALED_BIT; VkResult res; - if((res = vkCreateFence(Render_Core::get().getDevice().get(), &fenceInfo, nullptr, &_fence)) != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Vulkan : failed to create a synchronization object (fence), %s", RCore::verbaliseResultVk(res)); - #ifdef DEBUG - core::error::report(e_kind::message, "Vulkan : created new fence"); - #endif + if((res = vkCreateFence(RenderCore::Get().GetDevice().Get(), &fence_info, nullptr, &m_fence)) != VK_SUCCESS) + FatalError("Vulkan : failed to create a synchronization object (fence), %", VerbaliseVkResult(res)); + DebugLog("Vulkan : created new fence"); } - void Fence::wait() noexcept + void Fence::Wait() noexcept { - vkWaitForFences(Render_Core::get().getDevice().get(), 1, &_fence, VK_TRUE, UINT64_MAX); + vkWaitForFences(RenderCore::Get().GetDevice().Get(), 1, &m_fence, VK_TRUE, UINT64_MAX); } - void Fence::reset() noexcept + void Fence::Reset() noexcept { - vkResetFences(Render_Core::get().getDevice().get(), 1, &_fence); + vkResetFences(RenderCore::Get().GetDevice().Get(), 1, &m_fence); } - bool Fence::isReady() const noexcept + bool Fence::IsReady() const noexcept { - return vkGetFenceStatus(Render_Core::get().getDevice().get(), _fence) == VK_SUCCESS; + return vkGetFenceStatus(RenderCore::Get().GetDevice().Get(), m_fence) == VK_SUCCESS; } void Fence::destroy() noexcept { - if(_fence != VK_NULL_HANDLE) - vkDestroyFence(Render_Core::get().getDevice().get(), _fence, nullptr); - _fence = VK_NULL_HANDLE; - #ifdef DEBUG - core::error::report(e_kind::message, "Vulkan : destroyed fence"); - #endif + if(m_fence != VK_NULL_HANDLE) + vkDestroyFence(RenderCore::Get().GetDevice().Get(), m_fence, nullptr); + m_fence = VK_NULL_HANDLE; + DebugLog("Vulkan : destroyed fence"); } } diff --git a/runtime/Sources/Renderer/Core/Instance.cpp b/runtime/Sources/Renderer/Core/Instance.cpp index ad758ae..694e3b2 100644 --- a/runtime/Sources/Renderer/Core/Instance.cpp +++ b/runtime/Sources/Renderer/Core/Instance.cpp @@ -1,63 +1,67 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* vk_instance.cpp :+: :+: :+: */ +/* Instance.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/08 19:04:21 by maldavid #+# #+# */ -/* Updated: 2024/03/25 23:10:37 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 18:43:47 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ -#include +#include -#include "vk_instance.h" -#include "render_core.h" -#include +#include +#include namespace mlx { - void Instance::init() + void Instance::Init() { - VkApplicationInfo appInfo{}; - appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; - appInfo.pEngineName = "MacroLibX"; - appInfo.engineVersion = VK_MAKE_VERSION(1, 3, 1); - appInfo.apiVersion = VK_API_VERSION_1_2; + std::uint32_t api_version = std::min(volkGetInstanceVersion(), MLX_TARGET_VULKAN_API_VERSION); - auto extensions = getRequiredExtensions(); + if(api_version == 0) + FatalError("Vulkan API is not supported by this driver"); - VkInstanceCreateInfo createInfo{}; - createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - createInfo.pApplicationInfo = &appInfo; - createInfo.enabledExtensionCount = static_cast(extensions.size()); - createInfo.ppEnabledExtensionNames = extensions.data(); - createInfo.enabledLayerCount = 0; // will be replaced if validation layers are enabled - createInfo.pNext = nullptr; + m_instance_version = api_version; - VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo; - if constexpr(enableValidationLayers) + VkApplicationInfo app_info{}; + app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; + app_info.pEngineName = "MacroLibX"; + app_info.engineVersion = MLX_VERSION; + app_info.apiVersion = api_version; + + auto extensions = GetRequiredExtensions(); + + VkInstanceCreateInfo create_info{}; + create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + create_info.pApplicationInfo = &app_info; + create_info.enabledExtensionCount = static_cast(extensions.size()); + create_info.ppEnabledExtensionNames = extensions.data(); + create_info.enabledLayerCount = 0; // will be replaced if validation layers are enabled + create_info.pNext = nullptr; + + VkDebugUtilsMessengerCreateInfoEXT debug_create_info; + if constexpr(enable_validation_layers) { - if(Render_Core::get().getLayers().checkValidationLayerSupport()) + if(RenderCore::Get().GetLayers().CheckValidationLayerSupport()) { - createInfo.enabledLayerCount = static_cast(validationLayers.size()); - createInfo.ppEnabledLayerNames = validationLayers.data(); - Render_Core::get().getLayers().populateDebugMessengerCreateInfo(debugCreateInfo); - createInfo.pNext = static_cast(&debugCreateInfo); + create_info.enabledLayerCount = static_cast(validation_layers.size()); + create_info.ppEnabledLayerNames = validation_layers.data(); + RenderCore::Get().GetLayers().PopulateDebugMessengerCreateInfo(debug_create_info); + create_info.pNext = static_cast(&debug_create_info); } } VkResult res; - if((res = vkCreateInstance(&createInfo, nullptr, &_instance)) != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Vulkan : failed to create Vulkan instance, %s", RCore::verbaliseResultVk(res)); - volkLoadInstance(_instance); - #ifdef DEBUG - core::error::report(e_kind::message, "Vulkan : created new instance"); - #endif + if((res = vkCreateInstance(&create_info, nullptr, &m_instance)) != VK_SUCCESS) + FatalError("Vulkan : failed to create Vulkan instance, %", VerbaliseVkResult(res)); + volkLoadInstance(m_instance); + DebugLog("Vulkan : created new instance"); } - std::vector Instance::getRequiredExtensions() + std::vector Instance::GetRequiredExtensions() { std::uint32_t glfw_extension_count = 0; const char** glfw_extensions = glfwGetRequiredInstanceExtensions(&glfw_extension_count); @@ -75,12 +79,10 @@ namespace mlx return extensions; } - void Instance::destroy() noexcept + void Instance::Destroy() noexcept { - vkDestroyInstance(_instance, nullptr); - _instance = VK_NULL_HANDLE; - #ifdef DEBUG - core::error::report(e_kind::message, "Vulkan : destroyed an instance"); - #endif + vkDestroyInstance(m_instance, nullptr); + m_instance = VK_NULL_HANDLE; + DebugLog("Vulkan : destroyed an instance"); } } diff --git a/runtime/Sources/Renderer/Core/Memory.cpp b/runtime/Sources/Renderer/Core/Memory.cpp index 7c1568e..80ce793 100644 --- a/runtime/Sources/Renderer/Core/Memory.cpp +++ b/runtime/Sources/Renderer/Core/Memory.cpp @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* memory.cpp :+: :+: :+: */ +/* Memory.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: kbz_8 +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/20 22:02:37 by kbz_8 #+# #+# */ -/* Updated: 2024/03/25 19:27:44 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 18:49:10 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,7 +17,6 @@ #define VK_NO_PROTOTYPES #define VMA_STATIC_VULKAN_FUNCTIONS 0 #define VMA_DYNAMIC_VULKAN_FUNCTIONS 0 -#define VMA_VULKAN_VERSION 1002000 #define VMA_ASSERT(expr) ((void)0) #define VMA_IMPLEMENTATION @@ -39,11 +38,8 @@ #include #endif -#include - -#include -#include -#include +#include +#include namespace mlx { @@ -67,99 +63,99 @@ namespace mlx vma_vulkan_func.vkMapMemory = vkMapMemory; vma_vulkan_func.vkUnmapMemory = vkUnmapMemory; vma_vulkan_func.vkCmdCopyBuffer = vkCmdCopyBuffer; - vma_vulkan_func.vkGetBufferMemoryRequirements2KHR = vkGetBufferMemoryRequirements2; - vma_vulkan_func.vkGetImageMemoryRequirements2KHR = vkGetImageMemoryRequirements2; - vma_vulkan_func.vkBindBufferMemory2KHR = vkBindBufferMemory2; - vma_vulkan_func.vkBindImageMemory2KHR = vkBindImageMemory2; - vma_vulkan_func.vkGetPhysicalDeviceMemoryProperties2KHR = vkGetPhysicalDeviceMemoryProperties2; +#if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000 + vma_vulkan_func.vkGetBufferMemoryRequirements2KHR = vkGetBufferMemoryRequirements2, + vma_vulkan_func.vkGetImageMemoryRequirements2KHR = vkGetImageMemoryRequirements2, +#endif +#if VMA_BIND_MEMORY2 || VMA_VULKAN_VERSION >= 1001000 + vma_vulkan_func.vkBindBufferMemory2KHR = vkBindBufferMemory2, + vma_vulkan_func.vkBindImageMemory2KHR = vkBindImageMemory2, +#endif +#if VMA_MEMORY_BUDGET || VMA_VULKAN_VERSION >= 1001000 + vma_vulkan_func.vkGetPhysicalDeviceMemoryProperties2KHR = vkGetPhysicalDeviceMemoryProperties2, +#endif +#if VMA_VULKAN_VERSION >= 1003000 + vma_vulkan_func.vkGetDeviceBufferMemoryRequirements = vkGetDeviceBufferMemoryRequirements, + vma_vulkan_func.vkGetDeviceImageMemoryRequirements = vkGetDeviceImageMemoryRequirements, +#endif - VmaAllocatorCreateInfo allocatorCreateInfo{}; - allocatorCreateInfo.vulkanApiVersion = VK_API_VERSION_1_2; - allocatorCreateInfo.physicalDevice = Render_Core::get().getDevice().getPhysicalDevice(); - allocatorCreateInfo.device = Render_Core::get().getDevice().get(); - allocatorCreateInfo.instance = Render_Core::get().getInstance().get(); - allocatorCreateInfo.pVulkanFunctions = &vma_vulkan_func; + VmaAllocatorCreateInfo allocator_create_info{}; + allocator_create_info.vulkanApiVersion = RenderCore::Get().GetInstance().GetInstanceVersion(); + allocator_create_info.physicalDevice = RenderCore::Get().GetDevice().GetPhysicalDevice(); + allocator_create_info.device = RenderCore::Get().GetDevice().Get(); + allocator_create_info.instance = RenderCore::Get().GetInstance().Get(); + allocator_create_info.pVulkanFunctions = &vma_vulkan_func; - VkResult res = vmaCreateAllocator(&allocatorCreateInfo, &_allocator); + VkResult res = vmaCreateAllocator(&allocator_create_info, &m_allocator); if(res != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Graphics allocator : failed to create graphics memory allocator, %s", RCore::verbaliseResultVk(res)); - #ifdef DEBUG - core::error::report(e_kind::message, "Graphics allocator : created new allocator"); - #endif + FatalError("Graphics allocator : failed to create graphics memory allocator, %", VerbaliseVkResult(res)); + DebugLog("Graphics allocator : created new allocator"); } - VmaAllocation GPUallocator::createBuffer(const VkBufferCreateInfo* binfo, const VmaAllocationCreateInfo* vinfo, VkBuffer& buffer, const char* name) noexcept + VmaAllocation GPUallocator::CreateBuffer(const VkBufferCreateInfo* binfo, const VmaAllocationCreateInfo* vinfo, VkBuffer& buffer, const char* name) noexcept { MLX_PROFILE_FUNCTION(); VmaAllocation allocation; - VkResult res = vmaCreateBuffer(_allocator, binfo, vinfo, &buffer, &allocation, nullptr); + VkResult res = vmaCreateBuffer(m_allocator, binfo, vinfo, &buffer, &allocation, nullptr); if(res != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Graphics allocator : failed to allocate a buffer, %s", RCore::verbaliseResultVk(res)); + FatalError("Graphics allocator : failed to allocate a buffer, %s", RCore::verbaliseResultVk(res)); if(name != nullptr) { - Render_Core::get().getLayers().setDebugUtilsObjectNameEXT(VK_OBJECT_TYPE_BUFFER, (std::uint64_t)buffer, name); - vmaSetAllocationName(_allocator, allocation, name); + RenderCore::Get().GetLayers().SetDebugUtilsObjectNameEXT(VK_OBJECT_TYPE_BUFFER, (std::uint64_t)buffer, name); + vmaSetAllocationName(m_allocator, allocation, name); } - #ifdef DEBUG - core::error::report(e_kind::message, "Graphics Allocator : created new buffer '%s'", name); - #endif - _active_buffers_allocations++; + DebugLog("Graphics Allocator : created new buffer '%s'", name); + m_active_buffers_allocations++; return allocation; } - void GPUallocator::destroyBuffer(VmaAllocation allocation, VkBuffer buffer) noexcept + void GPUallocator::DestroyBuffer(VmaAllocation allocation, VkBuffer buffer) noexcept { MLX_PROFILE_FUNCTION(); - vkDeviceWaitIdle(Render_Core::get().getDevice().get()); - vmaDestroyBuffer(_allocator, buffer, allocation); - #ifdef DEBUG - core::error::report(e_kind::message, "Graphics Allocator : destroyed buffer"); - #endif - _active_buffers_allocations--; + vkDeviceWaitIdle(RenderCore::Get().GetDevice().Get()); + vmaDestroyBuffer(m_allocator, buffer, allocation); + DebugLog("Graphics Allocator : destroyed buffer"); + m_active_buffers_allocations--; } - VmaAllocation GPUallocator::createImage(const VkImageCreateInfo* iminfo, const VmaAllocationCreateInfo* vinfo, VkImage& image, const char* name) noexcept + VmaAllocation GPUallocator::CreateImage(const VkImageCreateInfo* iminfo, const VmaAllocationCreateInfo* vinfo, VkImage& image, const char* name) noexcept { MLX_PROFILE_FUNCTION(); VmaAllocation allocation; - VkResult res = vmaCreateImage(_allocator, iminfo, vinfo, &image, &allocation, nullptr); + VkResult res = vmaCreateImage(m_allocator, iminfo, vinfo, &image, &allocation, nullptr); if(res != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Graphics allocator : failed to allocate an image, %s", RCore::verbaliseResultVk(res)); + FatalError("Graphics allocator : failed to allocate an image, %", VerbaliseVkResult(res)); if(name != nullptr) { - Render_Core::get().getLayers().setDebugUtilsObjectNameEXT(VK_OBJECT_TYPE_IMAGE, (std::uint64_t)image, name); - vmaSetAllocationName(_allocator, allocation, name); + RenderCore::Get().GetLayers().SetDebugUtilsObjectNameEXT(VK_OBJECT_TYPE_IMAGE, (std::uint64_t)image, name); + vmaSetAllocationName(m_allocator, allocation, name); } - #ifdef DEBUG - core::error::report(e_kind::message, "Graphics Allocator : created new image '%s'", name); - #endif - _active_images_allocations++; + DebugLog("Graphics Allocator : created new image '%s'", name); + m_active_images_allocations++; return allocation; } - void GPUallocator::destroyImage(VmaAllocation allocation, VkImage image) noexcept + void GPUallocator::DestroyImage(VmaAllocation allocation, VkImage image) noexcept { MLX_PROFILE_FUNCTION(); - vkDeviceWaitIdle(Render_Core::get().getDevice().get()); - vmaDestroyImage(_allocator, image, allocation); - #ifdef DEBUG - core::error::report(e_kind::message, "Graphics Allocator : destroyed image"); - #endif - _active_images_allocations--; + vkDeviceWaitIdle(RenderCore::Get().GetDevice().Get()); + vmaDestroyImage(m_allocator, image, allocation); + DebugLog("Graphics Allocator : destroyed image"); + m_active_images_allocations--; } - void GPUallocator::mapMemory(VmaAllocation allocation, void** data) noexcept + void GPUallocator::MapMemory(VmaAllocation allocation, void** data) noexcept { MLX_PROFILE_FUNCTION(); - VkResult res = vmaMapMemory(_allocator, allocation, data); + VkResult res = vmaMapMemory(m_allocator, allocation, data); if(res != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Graphics allocator : unable to map GPU memory to CPU memory, %s", RCore::verbaliseResultVk(res)); + FatalError("Graphics allocator : unable to map GPU memory to CPU memory, %", VerbaliseVkResult(res)); } void GPUallocator::unmapMemory(VmaAllocation allocation) noexcept { MLX_PROFILE_FUNCTION(); - vmaUnmapMemory(_allocator, allocation); + vmaUnmapMemory(m_allocator, allocation); } void GPUallocator::dumpMemoryToJson() @@ -170,36 +166,34 @@ namespace mlx std::ofstream file(name); if(!file.is_open()) { - core::error::report(e_kind::error, "Graphics allocator : unable to dump memory to a json file"); + Error("Graphics allocator : unable to dump memory to a json file"); return; } char* str = nullptr; - vmaBuildStatsString(_allocator, &str, true); + vmaBuildStatsString(m_allocator, &str, true); file << str; - vmaFreeStatsString(_allocator, str); + vmaFreeStatsString(m_allocator, str); file.close(); id++; } - void GPUallocator::flush(VmaAllocation allocation, VkDeviceSize size, VkDeviceSize offset) noexcept + void GPUallocator::Flush(VmaAllocation allocation, VkDeviceSize size, VkDeviceSize offset) noexcept { MLX_PROFILE_FUNCTION(); - vmaFlushAllocation(_allocator, allocation, offset, size); + vmaFlushAllocation(m_allocator, allocation, offset, size); } - void GPUallocator::destroy() noexcept + void GPUallocator::Destroy() noexcept { - if(_active_images_allocations != 0) - core::error::report(e_kind::error, "Graphics allocator : some user-dependant allocations were not freed before destroying the display (%d active allocations). You may have not destroyed all the MLX resources you've created", _active_images_allocations); - else if(_active_buffers_allocations != 0) - core::error::report(e_kind::error, "Graphics allocator : some MLX-dependant allocations were not freed before destroying the display (%d active allocations). This is an error in the MLX, please report this should not happen", _active_buffers_allocations); - if(_active_images_allocations < 0 || _active_buffers_allocations < 0) - core::error::report(e_kind::warning, "Graphics allocator : the impossible happened, the MLX has freed more allocations than it has made (wtf)"); - vmaDestroyAllocator(_allocator); - _active_buffers_allocations = 0; - _active_images_allocations = 0; - #ifdef DEBUG - core::error::report(e_kind::message, "Vulkan : destroyed a graphics allocator"); - #endif + if(m_active_images_allocations != 0) + Error("Graphics allocator : some user-dependant allocations were not freed before destroying the display (% active allocations). You may have not destroyed all the MLX resources you've created", m_active_images_allocations); + else if(m_active_buffers_allocations != 0) + Error("Graphics allocator : some MLX-dependant allocations were not freed before destroying the display (% active allocations). This is an error in the MLX, please report this should not happen", m_active_buffers_allocations); + if(m_active_images_allocations < 0 || m_active_buffers_allocations < 0) + Warning("Graphics allocator : the impossible happened, the MLX has freed more allocations than it has made (wtf)"); + vmaDestroyAllocator(m_allocator); + m_active_buffers_allocations = 0; + m_active_images_allocations = 0; + DebugLog("Vulkan : destroyed a graphics allocator"); } } diff --git a/runtime/Sources/Renderer/Core/Queues.cpp b/runtime/Sources/Renderer/Core/Queues.cpp index b47fcf0..b1b7ae8 100644 --- a/runtime/Sources/Renderer/Core/Queues.cpp +++ b/runtime/Sources/Renderer/Core/Queues.cpp @@ -1,55 +1,53 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* vk_queues.cpp :+: :+: :+: */ +/* Queues.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/08 19:02:42 by maldavid #+# #+# */ -/* Updated: 2024/03/25 22:29:19 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 18:51:21 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ -#include +#include -#include "render_core.h" +#include namespace mlx { Queues::QueueFamilyIndices Queues::findQueueFamilies(VkPhysicalDevice device) { - std::uint32_t queueFamilyCount = 0; - vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr); + std::uint32_t queue_family_count = 0; + vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, nullptr); - std::vector queueFamilies(queueFamilyCount); - vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data()); + std::vector queue_families(queueFamilyCount); + vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, queue_families.data()); - _families = Queues::QueueFamilyIndices{}; + n_families = Queues::QueueFamilyIndices{}; int i = 0; - for(const auto& queueFamily : queueFamilies) + for(const auto& queue_family : queue_families) { - if(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) - _families->graphics_family = i; + if(queue_family.queueFlags & VK_QUEUE_GRAPHICS_BIT) + m_families->graphics_family = i; - if(glfwGetPhysicalDevicePresentationSupport(Render_Core::get().getInstance().get(), device, i)) - _families->present_family = i; + if(glfwGetPhysicalDevicePresentationSupport(RenderCore::Get().GetInstance().Get(), device, i)) + m_families->present_family = i; - if(_families->isComplete()) - return *_families; + if(m_families->IsComplete()) + return *m_families; i++; } - return *_families; + return *m_families; } - void Queues::init() + void Queues::Init() { - if(!_families.has_value()) - findQueueFamilies(Render_Core::get().getDevice().getPhysicalDevice()); - vkGetDeviceQueue(Render_Core::get().getDevice().get(), _families->graphics_family.value(), 0, &_graphics_queue); - vkGetDeviceQueue(Render_Core::get().getDevice().get(), _families->present_family.value(), 0, &_present_queue); - #ifdef DEBUG - core::error::report(e_kind::message, "Vulkan : got graphics and present queues"); - #endif + if(!m_families.has_value()) + FindQueueFamilies(RenderCore::Get().GetDevice().GetPhysicalDevice()); + vkGetDeviceQueue(RenderCore::Get().GetDevice().Get(), m_families->graphics_family.value(), 0, &m_graphics_queue); + vkGetDeviceQueue(RenderCore::Get().GetDevice().Get(), m_families->present_family.value(), 0, &m_present_queue); + DebugLog("Vulkan : got graphics and present queues"); } } diff --git a/runtime/Sources/Renderer/Core/RenderCore.cpp b/runtime/Sources/Renderer/Core/RenderCore.cpp index 6c14b53..44ced4a 100644 --- a/runtime/Sources/Renderer/Core/RenderCore.cpp +++ b/runtime/Sources/Renderer/Core/RenderCore.cpp @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* render_core.cpp :+: :+: :+: */ +/* RenderCore.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/12/17 23:33:34 by maldavid #+# #+# */ -/* Updated: 2024/03/25 19:02:06 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 18:54:26 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,10 +14,10 @@ #define VOLK_IMPLEMENTATION #include -#include +#include -#include -#include +#include +#include #ifdef DEBUG #ifdef MLX_COMPILER_MSVC @@ -29,124 +29,106 @@ namespace mlx { - namespace RCore + const char* VerbaliseVkResult(VkResult result) { - std::optional findMemoryType(std::uint32_t typeFilter, VkMemoryPropertyFlags properties, bool error) + switch(result) { - VkPhysicalDeviceMemoryProperties memProperties; - vkGetPhysicalDeviceMemoryProperties(Render_Core::get().getDevice().getPhysicalDevice(), &memProperties); + case VK_SUCCESS: return "Success"; + case VK_NOT_READY: return "A fence or query has not yet completed"; + case VK_TIMEOUT: return "A wait operation has not completed in the specified time"; + case VK_EVENT_SET: return "An event is signaled"; + case VK_EVENT_RESET: return "An event is unsignaled"; + case VK_INCOMPLETE: return "A return array was too small for the result"; + case VK_ERROR_OUT_OF_HOST_MEMORY: return "A host memory allocation has failed"; + case VK_ERROR_OUT_OF_DEVICE_MEMORY: return "A device memory allocation has failed"; + case VK_ERROR_INITIALIZATION_FAILED: return "Initialization of an object could not be completed for implementation-specific reasons"; + case VK_ERROR_DEVICE_LOST: return "The logical or physical device has been lost"; + case VK_ERROR_MEMORY_MAP_FAILED: return "Mapping of a memory object has failed"; + case VK_ERROR_LAYER_NOT_PRESENT: return "A requested layer is not present or could not be loaded"; + case VK_ERROR_EXTENSION_NOT_PRESENT: return "A requested extension is not supported"; + case VK_ERROR_FEATURE_NOT_PRESENT: return "A requested feature is not supported"; + case VK_ERROR_INCOMPATIBLE_DRIVER: return "The requested version of Vulkan is not supported by the driver or is otherwise incompatible"; + case VK_ERROR_TOO_MANY_OBJECTS: return "Too many objects of the type have already been created"; + case VK_ERROR_FORMAT_NOT_SUPPORTED: return "A requested format is not supported on this device"; + case VK_ERROR_SURFACE_LOST_KHR: return "A surface is no longer available"; + case VK_SUBOPTIMAL_KHR: return "A swapchain no longer matches the surface properties exactly, but can still be used"; + case VK_ERROR_OUT_OF_DATE_KHR: return "A surface has changed in such a way that it is no longer compatible with the swapchain"; + case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: return "The display used by a swapchain does not use the same presentable image layout"; + case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: return "The requested window is already connected to a VkSurfaceKHR, or to some other non-Vulkan API"; + case VK_ERROR_VALIDATION_FAILED_EXT: return "A validation layer found an error"; - for(std::uint32_t i = 0; i < memProperties.memoryTypeCount; i++) - { - if((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) - return i; - } - if(error) - core::error::report(e_kind::fatal_error, "Vulkan : failed to find suitable memory type"); - return std::nullopt; - } - - const char* verbaliseResultVk(VkResult result) - { - switch(result) - { - case VK_SUCCESS: return "Success"; - case VK_NOT_READY: return "A fence or query has not yet completed"; - case VK_TIMEOUT: return "A wait operation has not completed in the specified time"; - case VK_EVENT_SET: return "An event is signaled"; - case VK_EVENT_RESET: return "An event is unsignaled"; - case VK_INCOMPLETE: return "A return array was too small for the result"; - case VK_ERROR_OUT_OF_HOST_MEMORY: return "A host memory allocation has failed"; - case VK_ERROR_OUT_OF_DEVICE_MEMORY: return "A device memory allocation has failed"; - case VK_ERROR_INITIALIZATION_FAILED: return "Initialization of an object could not be completed for implementation-specific reasons"; - case VK_ERROR_DEVICE_LOST: return "The logical or physical device has been lost"; - case VK_ERROR_MEMORY_MAP_FAILED: return "Mapping of a memory object has failed"; - case VK_ERROR_LAYER_NOT_PRESENT: return "A requested layer is not present or could not be loaded"; - case VK_ERROR_EXTENSION_NOT_PRESENT: return "A requested extension is not supported"; - case VK_ERROR_FEATURE_NOT_PRESENT: return "A requested feature is not supported"; - case VK_ERROR_INCOMPATIBLE_DRIVER: return "The requested version of Vulkan is not supported by the driver or is otherwise incompatible"; - case VK_ERROR_TOO_MANY_OBJECTS: return "Too many objects of the type have already been created"; - case VK_ERROR_FORMAT_NOT_SUPPORTED: return "A requested format is not supported on this device"; - case VK_ERROR_SURFACE_LOST_KHR: return "A surface is no longer available"; - case VK_SUBOPTIMAL_KHR: return "A swapchain no longer matches the surface properties exactly, but can still be used"; - case VK_ERROR_OUT_OF_DATE_KHR: return "A surface has changed in such a way that it is no longer compatible with the swapchain"; - case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: return "The display used by a swapchain does not use the same presentable image layout"; - case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: return "The requested window is already connected to a VkSurfaceKHR, or to some other non-Vulkan API"; - case VK_ERROR_VALIDATION_FAILED_EXT: return "A validation layer found an error"; - - default: return "Unknown Vulkan error"; - } - return nullptr; - } - - VkPipelineStageFlags accessFlagsToPipelineStage(VkAccessFlags accessFlags, VkPipelineStageFlags stageFlags) - { - VkPipelineStageFlags stages = 0; - - while(accessFlags != 0) - { - VkAccessFlagBits AccessFlag = static_cast(accessFlags & (~(accessFlags - 1))); - if(AccessFlag == 0 || (AccessFlag & (AccessFlag - 1)) != 0) - core::error::report(e_kind::fatal_error, "Vulkan : an error has been caught during access flag to pipeline stage operation"); - accessFlags &= ~AccessFlag; - - switch(AccessFlag) - { - case VK_ACCESS_INDIRECT_COMMAND_READ_BIT: stages |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; break; - case VK_ACCESS_INDEX_READ_BIT: stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; break; - case VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT: stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; break; - case VK_ACCESS_UNIFORM_READ_BIT: stages |= stageFlags | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; break; - case VK_ACCESS_INPUT_ATTACHMENT_READ_BIT: stages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; break; - case VK_ACCESS_SHADER_READ_BIT: stages |= stageFlags | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; break; - case VK_ACCESS_SHADER_WRITE_BIT: stages |= stageFlags | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; break; - case VK_ACCESS_COLOR_ATTACHMENT_READ_BIT: stages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; break; - case VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT: stages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; break; - case VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT: stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; break; - case VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT: stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; break; - case VK_ACCESS_TRANSFER_READ_BIT: stages |= VK_PIPELINE_STAGE_TRANSFER_BIT; break; - case VK_ACCESS_TRANSFER_WRITE_BIT: stages |= VK_PIPELINE_STAGE_TRANSFER_BIT; break; - case VK_ACCESS_HOST_READ_BIT: stages |= VK_PIPELINE_STAGE_HOST_BIT; break; - case VK_ACCESS_HOST_WRITE_BIT: stages |= VK_PIPELINE_STAGE_HOST_BIT; break; - case VK_ACCESS_MEMORY_READ_BIT: break; - case VK_ACCESS_MEMORY_WRITE_BIT: break; - - default: core::error::report(e_kind::error, "Vulkan : unknown access flag"); break; - } - } - return stages; + default: return "Unknown Vulkan error"; } + return nullptr; } - void Render_Core::init() + VkPipelineStageFlags AccessFlagsToPipelineStage(VkAccessFlags access_flags, VkPipelineStageFlags stage_flags) + { + VkPipelineStageFlags stages = 0; + + while(access_flags != 0) + { + VkAccessFlagBits Access_flag = static_cast(access_flags & (~(access_flags - 1))); + if(Access_flag == 0 || (Access_flag & (Access_flag - 1)) != 0) + FatalError("Vulkan : an error has been caught during access flag to pipeline stage operation"); + access_flags &= ~Access_flag; + + switch(Access_flag) + { + case VK_ACCESS_INDIRECT_COMMAND_READ_BIT: stages |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT; break; + case VK_ACCESS_INDEX_READ_BIT: stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; break; + case VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT: stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT; break; + case VK_ACCESS_UNIFORM_READ_BIT: stages |= stage_flags | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; break; + case VK_ACCESS_INPUT_ATTACHMENT_READ_BIT: stages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; break; + case VK_ACCESS_SHADER_READ_BIT: stages |= stage_flags | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; break; + case VK_ACCESS_SHADER_WRITE_BIT: stages |= stage_flags | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; break; + case VK_ACCESS_COLOR_ATTACHMENT_READ_BIT: stages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; break; + case VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT: stages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; break; + case VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT: stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; break; + case VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT: stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; break; + case VK_ACCESS_TRANSFER_READ_BIT: stages |= VK_PIPELINE_STAGE_TRANSFER_BIT; break; + case VK_ACCESS_TRANSFER_WRITE_BIT: stages |= VK_PIPELINE_STAGE_TRANSFER_BIT; break; + case VK_ACCESS_HOST_READ_BIT: stages |= VK_PIPELINE_STAGE_HOST_BIT; break; + case VK_ACCESS_HOST_WRITE_BIT: stages |= VK_PIPELINE_STAGE_HOST_BIT; break; + case VK_ACCESS_MEMORY_READ_BIT: break; + case VK_ACCESS_MEMORY_WRITE_BIT: break; + + default: Error("Vulkan : unknown access flag"); break; + } + } + return stages; + } + + void RenderCore::Init() { if(volkInitialize() != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Vulkan loader : cannot load %s, are you sure Vulkan is installed on your system ?", VULKAN_LIB_NAME); + FatalError("Vulkan loader : cannot load %, are you sure Vulkan is installed on your system ?", VULKAN_LIB_NAME); - _instance.init(); - volkLoadInstance(_instance.get()); - _layers.init(); - _device.init(); - volkLoadDevice(_device.get()); - _queues.init(); - _allocator.init(); - _cmd_manager.init(); - _is_init = true; + m_instance.Init(); + volkLoadInstance(m_instance.Get()); + m_layers.Init(); + m_device.Init(); + volkLoadDevice(m_device.Get()); + m_queues.Init(); + m_allocator.Init(); + m_cmd_manager.Init(); + m_is_init = true; } - void Render_Core::destroy() + void RenderCore::Destroy() { - if(!_is_init) + if(!m_is_init) return; - vkDeviceWaitIdle(_device()); + vkDeviceWaitIdle(m_device.Get()); - _pool_manager.destroyAllPools(); - _cmd_manager.destroy(); - _allocator.destroy(); - _device.destroy(); - _layers.destroy(); - _instance.destroy(); + m_pool_manager.DestroyAllPools(); + m_cmd_manager.Destroy(); + m_allocator.Destroy(); + m_device.Destroy(); + m_layers.Destroy(); + m_instance.Destroy(); - _is_init = false; + m_is_init = false; } } diff --git a/runtime/Sources/Renderer/Core/Semaphore.cpp b/runtime/Sources/Renderer/Core/Semaphore.cpp index d8d8dd3..8a9d72a 100644 --- a/runtime/Sources/Renderer/Core/Semaphore.cpp +++ b/runtime/Sources/Renderer/Core/Semaphore.cpp @@ -1,45 +1,36 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* vk_semaphore.cpp :+: :+: :+: */ +/* Semaphore.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/08 19:01:08 by maldavid #+# #+# */ -/* Updated: 2024/03/25 19:02:25 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 18:55:42 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ -#include - -#include "vk_semaphore.h" -#include "render_core.h" -#include +#include +#include +#include namespace mlx { - void Semaphore::init() + void Semaphore::Init() { - VkSemaphoreCreateInfo semaphoreInfo{}; - semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + VkSemaphoreCreateInfo semaphore_info{}; + semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; VkResult res; - if( (res = vkCreateSemaphore(Render_Core::get().getDevice().get(), &semaphoreInfo, nullptr, &_image_available_semaphore)) != VK_SUCCESS || - (res = vkCreateSemaphore(Render_Core::get().getDevice().get(), &semaphoreInfo, nullptr, &_render_finished_semaphore)) != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Vulkan : failed to create a synchronization object (semaphore), %s", RCore::verbaliseResultVk(res)); - #ifdef DEBUG - core::error::report(e_kind::message, "Vulkan : created new semaphores"); - #endif + if((res = vkCreateSemaphore(RenderCore::Get().GetDevice().Get(), &semaphore_info, nullptr, &m_semaphore)) != VK_SUCCESS) + FatalError("Vulkan : failed to create a synchronization object (semaphore), %", VerbaliseVkResult(res)); + DebugLog("Vulkan : created new semaphores"); } - void Semaphore::destroy() noexcept + void Semaphore::Destroy() noexcept { - vkDestroySemaphore(Render_Core::get().getDevice().get(), _render_finished_semaphore, nullptr); - _render_finished_semaphore = VK_NULL_HANDLE; - vkDestroySemaphore(Render_Core::get().getDevice().get(), _image_available_semaphore, nullptr); - _image_available_semaphore = VK_NULL_HANDLE; - #ifdef DEBUG - core::error::report(e_kind::message, "Vulkan : destroyed semaphores"); - #endif + vkDestroySemaphore(RenderCore::Get().GetDevice().Get(), m_semaphore, nullptr); + m_semaphore = VK_NULL_HANDLE; + DebugLog("Vulkan : destroyed semaphore"); } } diff --git a/runtime/Sources/Renderer/Core/Surface.cpp b/runtime/Sources/Renderer/Core/Surface.cpp index b50a5f2..4715afe 100644 --- a/runtime/Sources/Renderer/Core/Surface.cpp +++ b/runtime/Sources/Renderer/Core/Surface.cpp @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* vk_surface.cpp :+: :+: :+: */ +/* Surface.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/08 18:58:49 by maldavid #+# #+# */ -/* Updated: 2024/03/25 22:25:55 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 18:56:56 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,31 +17,27 @@ namespace mlx { - void Surface::create(Renderer& renderer) + void Surface::Create(Renderer& renderer) { - if(glfwCreateWindowSurface(Render_Core::get().getInstance().get(), renderer.getWindow()->getNativeWindow(), NULL, &_surface) != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Vulkan : failed to create a surface"); - #ifdef DEBUG - core::error::report(e_kind::message, "Vulkan : created new surface"); - #endif + if(glfwCreateWindowSurface(RenderCore::Get().GetInstance().Get(), renderer.GetWindow()->GetNativeWindow(), NULL, &m_surface) != VK_SUCCESS) + FatalError("Vulkan : failed to create a surface"); + DebugLog("Vulkan : created new surface"); } - VkSurfaceFormatKHR Surface::chooseSwapSurfaceFormat(const std::vector& availableFormats) + VkSurfaceFormatKHR Surface::ChooseSwapSurfaceFormat(const std::vector& available_formats) { - auto it = std::find_if(availableFormats.begin(), availableFormats.end(), [](VkSurfaceFormatKHR format) + auto it = std::find_if(available_formats.begin(), available_formats.end(), [](VkSurfaceFormatKHR format) { return format.format == VK_FORMAT_R8G8B8A8_SRGB && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; }); - return (it == availableFormats.end() ? availableFormats[0] : *it); + return (it == available_formats.end() ? available_formats[0] : *it); } - void Surface::destroy() noexcept + void Surface::Destroy() noexcept { - vkDestroySurfaceKHR(Render_Core::get().getInstance().get(), _surface, nullptr); - _surface = VK_NULL_HANDLE; - #ifdef DEBUG - core::error::report(e_kind::message, "Vulkan : destroyed a surface"); - #endif + vkDestroySurfaceKHR(RenderCore::Get().GetInstance().Get(), m_surface, nullptr); + m_surface = VK_NULL_HANDLE; + DebugLog("Vulkan : destroyed a surface"); } } diff --git a/runtime/Sources/Renderer/Core/ValidationLayers.cpp b/runtime/Sources/Renderer/Core/ValidationLayers.cpp index ffecd3d..d64a033 100644 --- a/runtime/Sources/Renderer/Core/ValidationLayers.cpp +++ b/runtime/Sources/Renderer/Core/ValidationLayers.cpp @@ -1,79 +1,72 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* vk_validation_layers.cpp :+: :+: :+: */ +/* ValidationLayers.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/12/19 14:05:25 by maldavid #+# #+# */ -/* Updated: 2024/03/25 19:00:06 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 19:20:21 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ -#include -#include "render_core.h" -#include "vulkan/vulkan_core.h" - -#include +#include +#include namespace mlx { - void ValidationLayers::init() + void ValidationLayers::Init() { - if constexpr(!enableValidationLayers) + if constexpr(!enable_validation_layers) return; - std::uint32_t extensionCount; - vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr); - std::vector extensions(extensionCount); - vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.data()); + std::uint32_t extension_count; + vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr); + std::vector extensions(extension_count); + vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extensions.data()); if(!std::any_of(extensions.begin(), extensions.end(), [=](VkExtensionProperties ext) { return std::strcmp(ext.extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0; })) { - core::error::report(e_kind::warning , "Vulkan : %s not present, debug utils are disabled", VK_EXT_DEBUG_UTILS_EXTENSION_NAME); + Warning("Vulkan : %s not present, debug utils are disabled", VK_EXT_DEBUG_UTILS_EXTENSION_NAME); return; } - VkDebugUtilsMessengerCreateInfoEXT createInfo{}; - populateDebugMessengerCreateInfo(createInfo); - VkResult res = createDebugUtilsMessengerEXT(&createInfo, nullptr); + VkDebugUtilsMessengerCreateInfoEXT create_info{}; + populateDebugMessengerCreateInfo(create_info); + VkResult res = createDebugUtilsMessengerEXT(&create_info, nullptr); if(res != VK_SUCCESS) - core::error::report(e_kind::warning, "Vulkan : failed to set up debug messenger, %s", RCore::verbaliseResultVk(res)); - #ifdef DEBUG + Warning("Vulkan : failed to set up debug messenger, %", VerbaliseVkResult(res)); else - core::error::report(e_kind::message, "Vulkan : enabled validation layers"); - #endif + DebugLog("Vulkan : enabled validation layers"); - _vkSetDebugUtilsObjectNameEXT = (PFN_vkSetDebugUtilsObjectNameEXT)vkGetInstanceProcAddr(Render_Core::get().getInstance().get(), "vkSetDebugUtilsObjectNameEXT"); - if(!_vkSetDebugUtilsObjectNameEXT) - core::error::report(e_kind::warning, "Vulkan : failed to set up debug object names, %s", RCore::verbaliseResultVk(VK_ERROR_EXTENSION_NOT_PRESENT)); - #ifdef DEBUG + f_vkSetDebugUtilsObjectNameEXT = (PFN_vkSetDebugUtilsObjectNameEXT)vkGetInstanceProcAddr(RenderCore::Get().GetInstance().Get(), "vkSetDebugUtilsObjectNameEXT"); + if(!f_vkSetDebugUtilsObjectNameEXT) + Warning("Vulkan : failed to set up debug object names, %", VerbaliseVkResult(VK_ERROR_EXTENSION_NOT_PRESENT)); else - core::error::report(e_kind::message, "Vulkan : enabled debug object names"); - #endif + DebugLog("Vulkan : enabled debug object names"); } - bool ValidationLayers::checkValidationLayerSupport() + bool ValidationLayers::CheckValidationLayerSupport() { - std::uint32_t layerCount; - vkEnumerateInstanceLayerProperties(&layerCount, nullptr); + std::uint32_t layer_count; + vkEnumerateInstanceLayerProperties(&layer_count, nullptr); - std::vector availableLayers(layerCount); - vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data()); + std::vector available_layers(layer_count); + vkEnumerateInstanceLayerProperties(&layer_count, available_layers.data()); - return std::all_of(validationLayers.begin(), validationLayers.end(), [&](const char* layerName) + return std::all_of(validation_layers.begin(), validation_layers.end(), [&](const char* layer_name) { - if(!std::any_of(availableLayers.begin(), availableLayers.end(), [=](VkLayerProperties props) { return std::strcmp(layerName, props.layerName) == 0; })) + if(!std::any_of(available_layers.begin(), available_layers.end(), [=](VkLayerProperties props) { return std::strcmp(layer_name, props.layer_name) == 0; })) { - core::error::report(e_kind::error, "Vulkan : a validation layer was requested but was not found ('%s')", layerName); + Error("Vulkan : a validation layer was requested but was not found ('%')", layer_name); return false; } return true; }); } - VkResult ValidationLayers::setDebugUtilsObjectNameEXT(VkObjectType object_type, std::uint64_t object_handle, const char* object_name) + VkResult ValidationLayers::SetDebugUtilsObjectNameEXT(VkObjectType object_type, std::uint64_t object_handle, const char* object_name) { - if(!_vkSetDebugUtilsObjectNameEXT) + if(!f_vkSetDebugUtilsObjectNameEXT) return VK_ERROR_EXTENSION_NOT_PRESENT; VkDebugUtilsObjectNameInfoEXT name_info{}; @@ -81,49 +74,49 @@ namespace mlx name_info.objectType = object_type; name_info.objectHandle = object_handle; name_info.pObjectName = object_name; - return _vkSetDebugUtilsObjectNameEXT(Render_Core::get().getDevice().get(), &name_info); + return f_vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice().Get(), &name_info); } - void ValidationLayers::populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& createInfo) + void ValidationLayers::PopulateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& create_info) { - createInfo = {}; - createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; - createInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; - createInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; - createInfo.pfnUserCallback = ValidationLayers::debugCallback; + create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; + create_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; + create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; + create_info.pfnUserCallback = ValidationLayers::DebugCallback; } - void ValidationLayers::destroy() + void ValidationLayers::Destroy() { - if constexpr(enableValidationLayers) + if constexpr(enable_validation_layers) { - destroyDebugUtilsMessengerEXT(nullptr); + DestroyDebugUtilsMessengerEXT(nullptr); #ifdef DEBUG - core::error::report(e_kind::message, "Vulkan : destroyed validation layers"); + DebugLog("Vulkan : destroyed validation layers"); #endif } } - VkResult ValidationLayers::createDebugUtilsMessengerEXT(const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator) + VkResult ValidationLayers::CreateDebugUtilsMessengerEXT(const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator) { - auto func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(Render_Core::get().getInstance().get(), "vkCreateDebugUtilsMessengerEXT"); - return func != nullptr ? func(Render_Core::get().getInstance().get(), pCreateInfo, pAllocator, &_debug_messenger) : VK_ERROR_EXTENSION_NOT_PRESENT; + auto func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(RenderCore::Get().GetInstance().Get(), "vkCreateDebugUtilsMessengerEXT"); + return func != nullptr ? func(RenderCore::Get().GetInstance().Get(), pCreateInfo, pAllocator, &m_debug_messenger) : VK_ERROR_EXTENSION_NOT_PRESENT; } - VKAPI_ATTR VkBool32 VKAPI_CALL ValidationLayers::debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, [[maybe_unused]] VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, [[maybe_unused]] void* pUserData) + VKAPI_ATTR VkBool32 VKAPI_CALL ValidationLayers::DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, [[maybe_unused]] VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, [[maybe_unused]] void* pUserData) { if(messageSeverity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) - core::error::report(e_kind::error, pCallbackData->pMessage); + Error(pCallbackData->pMessage); else if(messageSeverity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) - core::error::report(e_kind::warning, pCallbackData->pMessage); + Warning(pCallbackData->pMessage); return VK_FALSE; } void ValidationLayers::destroyDebugUtilsMessengerEXT(const VkAllocationCallbacks* pAllocator) { - auto func = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(Render_Core::get().getInstance().get(), "vkDestroyDebugUtilsMessengerEXT"); + auto func = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(RenderCore::Get().GetInstance().Get(), "vkDestroyDebugUtilsMessengerEXT"); if(func != nullptr) - func(Render_Core::get().getInstance().get(), _debug_messenger, pAllocator); + func(RenderCore::Get().GetInstance().Get(), m_debug_messenger, pAllocator); } } diff --git a/runtime/Sources/Renderer/Descriptors/DescriptorPool.cpp b/runtime/Sources/Renderer/Descriptors/DescriptorPool.cpp new file mode 100644 index 0000000..2cd8085 --- /dev/null +++ b/runtime/Sources/Renderer/Descriptors/DescriptorPool.cpp @@ -0,0 +1,69 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* DescriptorPool.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maldavid +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/01/23 18:34:23 by maldavid #+# #+# */ +/* Updated: 2024/04/23 19:39:39 by maldavid ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include + +#include +#include +#include + +namespace mlx +{ + void DescriptorPool::Init(std::vector sizes) + { + VkDescriptorPoolCreateInfo pool_info{}; + pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + pool_info.poolSizeCount = sizes.size(); + pool_info.pPoolSizes = sizes.data(); + pool_info.maxSets = MAX_SETS_PER_POOL; + pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; + + VkResult res = vkCreateDescriptorPool(RenderCore::Get().GetDevice().Get(), &pool_info, nullptr, &m_pool); + if(res != VK_SUCCESS) + FatalError("Vulkan : failed to create descriptor pool, %", VerbaliseVkResult(res)); + DebugLog("Vulkan : created new descriptor pool"); + } + + VkDescriptorSet DescriptorPool::AllocateDescriptorSet(class DescriptorSetLayout& layout) + { + VkDescriptorSet set; + + VkDescriptorSetAllocateInfo alloc_info{}; + alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + alloc_info.descriptorPool = m_pool; + alloc_info.descriptorSetCount = 1; + alloc_info.pSetLayouts = layouts.Get(); + + VkResult res = vkAllocateDescriptorSets(RenderCore::Get().GetDevice().Get(), &alloc_info, &set); + if(res != VK_SUCCESS) + FatalError("Vulkan : failed to allocate descriptor set, %", VerbaliseVkResult(res)); + m_allocated_sets++; + DebugLog("Vulkan : created new descriptor set"); + return set; + } + + void DescriptorPool::FreeDescriptor(VkDescriptorSet set) + { + if(!IsInit()) + return; + vkFreeDescriptorSets(RenderCore::Get().GetDevice().Get(), m_pool, 1, set); + m_allocated_sets--; // if this goes underflow I quit + } + + void DescriptorPool::Destroy() noexcept + { + if(m_pool != VK_NULL_HANDLE) + vkDestroyDescriptorPool(RenderCore::Get().GetDevice().Get(), m_pool, nullptr); + m_pool = VK_NULL_HANDLE; + DebugLog("Vulkan : destroyed a descriptor pool"); + } +} diff --git a/runtime/Sources/Renderer/Descriptors/descriptor_pool_manager.cpp b/runtime/Sources/Renderer/Descriptors/DescriptorPoolManager.cpp similarity index 60% rename from runtime/Sources/Renderer/Descriptors/descriptor_pool_manager.cpp rename to runtime/Sources/Renderer/Descriptors/DescriptorPoolManager.cpp index 4279527..081f887 100644 --- a/runtime/Sources/Renderer/Descriptors/descriptor_pool_manager.cpp +++ b/runtime/Sources/Renderer/Descriptors/DescriptorPoolManager.cpp @@ -1,41 +1,41 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* descriptor_pool_manager.cpp :+: :+: :+: */ +/* DescriptorPoolManager.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/20 06:51:47 by maldavid #+# #+# */ -/* Updated: 2024/03/25 19:02:29 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 19:41:38 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ -#include +#include -#include -#include +#include +#include namespace mlx { - DescriptorPool& DescriptorPoolManager::getAvailablePool() + DescriptorPool& DescriptorPoolManager::GetAvailablePool() { - for(auto& pool : _pools) + for(auto& pool : m_pools) { - if(pool.getNumberOfSetsAllocated() < MAX_SETS_PER_POOL) + if(pool.GetNumberOfSetsAllocated() < MAX_SETS_PER_POOL) return pool; } - VkDescriptorPoolSize pool_sizes[] = { + std::vector pool_sizes = { { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, (MAX_FRAMES_IN_FLIGHT * NUMBER_OF_UNIFORM_BUFFERS) }, { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, MAX_SETS_PER_POOL - (MAX_FRAMES_IN_FLIGHT * NUMBER_OF_UNIFORM_BUFFERS) } }; - _pools.emplace_front().init((sizeof(pool_sizes) / sizeof(VkDescriptorPoolSize)), pool_sizes); - return _pools.front(); + m_pools.emplace_front().Init(std::move(pool_sizes)); + return m_pools.front(); } - void DescriptorPoolManager::destroyAllPools() + void DescriptorPoolManager::DestroyAllPools() { - for(auto& pool : _pools) - pool.destroy(); - _pools.clear(); + for(auto& pool : m_pools) + pool.Destroy(); + m_pools.clear(); } } diff --git a/runtime/Sources/Renderer/Descriptors/DescriptorSet.cpp b/runtime/Sources/Renderer/Descriptors/DescriptorSet.cpp new file mode 100644 index 0000000..b28ba9b --- /dev/null +++ b/runtime/Sources/Renderer/Descriptors/DescriptorSet.cpp @@ -0,0 +1,111 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* DescriptorSet.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maldavid +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/01/23 18:40:44 by maldavid #+# #+# */ +/* Updated: 2024/04/23 19:50:06 by maldavid ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include + +#include +#include +#include +#include +#include +#include + +namespace mlx +{ + void DescriptorSet::Init(NonOwningPtr renderer, NonOwningPtr pool, DescriptorSetLayout layout) + { + MLX_PROFILE_FUNCTION(); + m_renderer = renderer; + m_layout = layout; + m_pool = pool; + + for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) + m_desc_set[i] = pool->AllocateDescriptorSet(layout); + } + + void DescriptorSet::WriteDescriptor(int binding, NonOwningPtr ubo) const noexcept + { + MLX_PROFILE_FUNCTION(); + auto device = RenderCore::Get().GetDevice().Get(); + + for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) + { + VkDescriptorBufferInfo buffer_info{}; + buffer_info.buffer = ubo->Get(i); + buffer_info.offset = ubo->GetOffset(i); + buffer_info.range = ubo->GetSize(i); + + VkWriteDescriptorSet descriptor_write{}; + descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptor_write.dstSet = m_desc_set[i]; + descriptor_write.dstBinding = binding; + descriptor_write.dstArrayElement = 0; + descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + descriptor_write.descriptorCount = 1; + descriptor_write.pBufferInfo = &buffer_info; + + vkUpdateDescriptorSets(device, 1, &descriptor_write, 0, nullptr); + } + } + + void DescriptorSet::WriteDescriptor(int binding, const Image& image) const noexcept + { + MLX_PROFILE_FUNCTION(); + auto device = RenderCore::Get().GetDevice().Get(); + + VkDescriptorImageInfo image_info{}; + image_info.imageLayout = image.GetLayout(); + image_info.imageView = image.GetImageView(); + image_info.sampler = image.GetSampler(); + + VkWriteDescriptorSet descriptor_write{}; + descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptor_write.dstSet = m_desc_set[m_renderer->GetActiveImageIndex()]; + descriptor_write.dstBinding = binding; + descriptor_write.dstArrayElement = 0; + descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descriptor_write.descriptorCount = 1; + descriptor_write.pImageInfo = &image_info; + + vkUpdateDescriptorSets(device, 1, &descriptor_write, 0, nullptr); + } + + DescriptorSet DescriptorSet::Duplicate() + { + MLX_PROFILE_FUNCTION(); + DescriptorSet set; + set.Init(m_renderer, &RenderCore::Get().GetDescriptorPool(), m_layout); + return set; + } + + VkDescriptorSet& DescriptorSet::operator()() noexcept + { + return m_desc_set[m_renderer->GetActiveImageIndex()]; + } + + VkDescriptorSet& DescriptorSet::Get() noexcept + { + return m_desc_set[m_renderer->GetActiveImageIndex()]; + } + + void DescriptorSet::Destroy() noexcept + { + 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) + m_pool->FreeDescriptor(*this); + for(auto& set : m_desc_set) + { + if(set != VK_NULL_HANDLE) + set = VK_NULL_HANDLE; + } + } +} diff --git a/runtime/Sources/Renderer/Descriptors/vk_descriptor_set_layout.cpp b/runtime/Sources/Renderer/Descriptors/DescriptorSetLayout.cpp similarity index 56% rename from runtime/Sources/Renderer/Descriptors/vk_descriptor_set_layout.cpp rename to runtime/Sources/Renderer/Descriptors/DescriptorSetLayout.cpp index 4ceba14..cc61a34 100644 --- a/runtime/Sources/Renderer/Descriptors/vk_descriptor_set_layout.cpp +++ b/runtime/Sources/Renderer/Descriptors/DescriptorSetLayout.cpp @@ -1,23 +1,23 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* vk_descriptor_set_layout.cpp :+: :+: :+: */ +/* DescriptorSetLayout.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/01/23 18:37:28 by maldavid #+# #+# */ -/* Updated: 2024/03/25 19:02:47 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 19:52:41 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ -#include +#include -#include "vk_descriptor_set_layout.h" -#include +#include +#include namespace mlx { - void DescriptorSetLayout::init(std::vector> binds, VkShaderStageFlagBits stage) + void DescriptorSetLayout::Init(std::vector> binds, VkShaderStageFlagBits stage) { std::vector bindings(binds.size()); for(std::size_t i = 0; i < binds.size(); i++) @@ -29,21 +29,21 @@ namespace mlx bindings[i].stageFlags = stage; } - _bindings = std::move(binds); + m_bindings = std::move(binds); - VkDescriptorSetLayoutCreateInfo layoutInfo{}; - layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - layoutInfo.bindingCount = _bindings.size(); - layoutInfo.pBindings = bindings.data(); + VkDescriptorSetLayoutCreateInfo layout_info{}; + layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + layout_info.bindingCount = m_bindings.size(); + layout_info.pBindings = m_bindings.data(); - VkResult res = vkCreateDescriptorSetLayout(Render_Core::get().getDevice().get(), &layoutInfo, nullptr, &_layout); + VkResult res = vkCreateDescriptorSetLayout(RenderCore::Get().GetDevice().Get(), &layout_info, nullptr, &m_layout); if(res != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Vulkan : failed to create descriptor set layout, %s", RCore::verbaliseResultVk(res)); + FatalError("Vulkan : failed to create descriptor set layout, %", VerbaliseVkResult(res)); } - void DescriptorSetLayout::destroy() noexcept + void DescriptorSetLayout::Destroy() noexcept { - vkDestroyDescriptorSetLayout(Render_Core::get().getDevice().get(), _layout, nullptr); - _layout = VK_NULL_HANDLE; + vkDestroyDescriptorSetLayout(RenderCore::Get().GetDevice().Get(), m_layout, nullptr); + m_layout = VK_NULL_HANDLE; } } diff --git a/runtime/Sources/Renderer/Descriptors/vk_descriptor_pool.cpp b/runtime/Sources/Renderer/Descriptors/vk_descriptor_pool.cpp deleted file mode 100644 index 87f44ce..0000000 --- a/runtime/Sources/Renderer/Descriptors/vk_descriptor_pool.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* vk_descriptor_pool.cpp :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: maldavid +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2023/01/23 18:34:23 by maldavid #+# #+# */ -/* Updated: 2024/03/25 19:02:37 by maldavid ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include - -#include "vk_descriptor_pool.h" -#include -#include - -namespace mlx -{ - void DescriptorPool::init(std::size_t n, VkDescriptorPoolSize* size) - { - VkDescriptorPoolCreateInfo poolInfo{}; - poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - poolInfo.poolSizeCount = n; - poolInfo.pPoolSizes = size; - poolInfo.maxSets = MAX_SETS_PER_POOL; - poolInfo.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; - - VkResult res = vkCreateDescriptorPool(Render_Core::get().getDevice().get(), &poolInfo, nullptr, &_pool); - if(res != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Vulkan : failed to create descriptor pool, %s", RCore::verbaliseResultVk(res)); - _allocated_sets++; - #ifdef DEBUG - core::error::report(e_kind::message, "Vulkan : created new descriptor pool"); - #endif - } - - void DescriptorPool::freeDescriptor(const DescriptorSet& set) - { - if(!isInit()) - return; - const auto& sets = set.getAllFramesDescriptorSets(); - vkFreeDescriptorSets(Render_Core::get().getDevice().get(), _pool, sets.size(), sets.data()); - _allocated_sets--; // if this goes in underflow I quit - } - - void DescriptorPool::destroy() noexcept - { - if(_pool != VK_NULL_HANDLE) - vkDestroyDescriptorPool(Render_Core::get().getDevice().get(), _pool, nullptr); - _pool = VK_NULL_HANDLE; - #ifdef DEBUG - core::error::report(e_kind::message, "Vulkan : destroyed a descriptor pool"); - #endif - } -} diff --git a/runtime/Sources/Renderer/Descriptors/vk_descriptor_set.cpp b/runtime/Sources/Renderer/Descriptors/vk_descriptor_set.cpp deleted file mode 100644 index 07a5841..0000000 --- a/runtime/Sources/Renderer/Descriptors/vk_descriptor_set.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* vk_descriptor_set.cpp :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: maldavid +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2023/01/23 18:40:44 by maldavid #+# #+# */ -/* Updated: 2024/03/25 19:02:43 by maldavid ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include - -#include "vk_descriptor_set.h" -#include "renderer/core/render_core.h" -#include "vk_descriptor_pool.h" -#include "vk_descriptor_set_layout.h" -#include -#include -#include -#include - -namespace mlx -{ - void DescriptorSet::init(Renderer* renderer, DescriptorPool* pool, DescriptorSetLayout* layout) - { - MLX_PROFILE_FUNCTION(); - _renderer = renderer; - _layout = layout; - _pool = pool; - - auto device = Render_Core::get().getDevice().get(); - - std::array layouts; - layouts.fill(layout->get()); - - VkDescriptorSetAllocateInfo allocInfo{}; - allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; - allocInfo.descriptorPool = _pool->get(); - allocInfo.descriptorSetCount = static_cast(MAX_FRAMES_IN_FLIGHT); - allocInfo.pSetLayouts = layouts.data(); - - VkResult res = vkAllocateDescriptorSets(device, &allocInfo, _desc_set.data()); - if(res != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Vulkan : failed to allocate descriptor set, %s", RCore::verbaliseResultVk(res)); - #ifdef DEBUG - core::error::report(e_kind::message, "Vulkan : created new descriptor set"); - #endif - } - - void DescriptorSet::writeDescriptor(int binding, UBO* ubo) const noexcept - { - MLX_PROFILE_FUNCTION(); - auto device = Render_Core::get().getDevice().get(); - - for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) - { - VkDescriptorBufferInfo bufferInfo{}; - bufferInfo.buffer = ubo->get(i); - bufferInfo.offset = ubo->getOffset(i); - bufferInfo.range = ubo->getSize(i); - - VkWriteDescriptorSet descriptorWrite{}; - descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptorWrite.dstSet = _desc_set[i]; - descriptorWrite.dstBinding = binding; - descriptorWrite.dstArrayElement = 0; - descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - descriptorWrite.descriptorCount = 1; - descriptorWrite.pBufferInfo = &bufferInfo; - - vkUpdateDescriptorSets(device, 1, &descriptorWrite, 0, nullptr); - } - } - - void DescriptorSet::writeDescriptor(int binding, const Image& image) const noexcept - { - MLX_PROFILE_FUNCTION(); - auto device = Render_Core::get().getDevice().get(); - - VkDescriptorImageInfo imageInfo{}; - imageInfo.imageLayout = image.getLayout(); - imageInfo.imageView = image.getImageView(); - imageInfo.sampler = image.getSampler(); - - VkWriteDescriptorSet descriptorWrite{}; - descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptorWrite.dstSet = _desc_set[_renderer->getActiveImageIndex()]; - descriptorWrite.dstBinding = binding; - descriptorWrite.dstArrayElement = 0; - descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - descriptorWrite.descriptorCount = 1; - descriptorWrite.pImageInfo = &imageInfo; - - vkUpdateDescriptorSets(device, 1, &descriptorWrite, 0, nullptr); - } - - DescriptorSet DescriptorSet::duplicate() - { - MLX_PROFILE_FUNCTION(); - DescriptorSet set; - set.init(_renderer, &Render_Core::get().getDescriptorPool(), _layout); - return set; - } - - VkDescriptorSet& DescriptorSet::operator()() noexcept - { - return _desc_set[_renderer->getActiveImageIndex()]; - } - - VkDescriptorSet& DescriptorSet::get() noexcept - { - return _desc_set[_renderer->getActiveImageIndex()]; - } - - void DescriptorSet::destroy() noexcept - { - MLX_PROFILE_FUNCTION(); - if(_pool != nullptr && Render_Core::get().isInit()) // checks if the render core is still init (it should always be init but just in case) - _pool->freeDescriptor(*this); - for(auto& set : _desc_set) - { - if(set != VK_NULL_HANDLE) - set = VK_NULL_HANDLE; - } - #ifdef DEBUG - core::error::report(e_kind::message, "Vulkan : destroyed descriptor set"); - #endif - } -} diff --git a/runtime/Sources/Renderer/Images/vk_image.cpp b/runtime/Sources/Renderer/Images/Image.cpp similarity index 60% rename from runtime/Sources/Renderer/Images/vk_image.cpp rename to runtime/Sources/Renderer/Images/Image.cpp index 28f9054..d6e62ba 100644 --- a/runtime/Sources/Renderer/Images/vk_image.cpp +++ b/runtime/Sources/Renderer/Images/Image.cpp @@ -1,26 +1,23 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* vk_image.cpp :+: :+: :+: */ +/* Image.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/01/25 11:59:07 by maldavid #+# #+# */ -/* Updated: 2024/03/25 19:03:27 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 20:02:25 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ -#include +#include -#include "vk_image.h" -#include -#include -#include -#include +#include +#include namespace mlx { - bool isStencilFormat(VkFormat format) + bool IsStencilFormat(VkFormat format) { switch(format) { @@ -32,7 +29,7 @@ namespace mlx } } - bool isDepthFormat(VkFormat format) + bool IsDepthFormat(VkFormat format) { switch(format) { @@ -47,7 +44,7 @@ namespace mlx } } - VkFormat bitsToFormat(std::uint32_t bits) + VkFormat BitsToFormat(std::uint32_t bits) { switch(bits) { @@ -61,67 +58,67 @@ namespace mlx case 128: return VK_FORMAT_R32G32B32A32_SFLOAT; default: - core::error::report(e_kind::fatal_error, "Vulkan : unsupported image bit-depth"); + FatalError("Vulkan : unsupported image bit-depth"); return VK_FORMAT_R8G8B8A8_UNORM; } } - VkPipelineStageFlags layoutToAccessMask(VkImageLayout layout, bool isDestination) + VkPipelineStageFlags LayoutToAccessMask(VkImageLayout layout, bool is_destination) { - VkPipelineStageFlags accessMask = 0; + VkPipelineStageFlags access_mask = 0; switch(layout) { case VK_IMAGE_LAYOUT_UNDEFINED: - if(isDestination) - core::error::report(e_kind::error, "Vulkan : the new layout used in a transition must not be VK_IMAGE_LAYOUT_UNDEFINED"); + if(is_destination) + Error("Vulkan : the new layout used in a transition must not be VK_IMAGE_LAYOUT_UNDEFINED"); break; - case VK_IMAGE_LAYOUT_GENERAL: accessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; break; - case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: accessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; break; - case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: accessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; break; + case VK_IMAGE_LAYOUT_GENERAL: access_mask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; break; + case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: access_mask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; break; + case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: access_mask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; break; case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: - accessMask = VK_ACCESS_SHADER_READ_BIT; // VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; + access_mask = VK_ACCESS_SHADER_READ_BIT; // VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; break; - case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: accessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; break; - case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: accessMask = VK_ACCESS_TRANSFER_READ_BIT; break; - case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: accessMask = VK_ACCESS_TRANSFER_WRITE_BIT; break; + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: access_mask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; break; + case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: access_mask = VK_ACCESS_TRANSFER_READ_BIT; break; + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: access_mask = VK_ACCESS_TRANSFER_WRITE_BIT; break; case VK_IMAGE_LAYOUT_PREINITIALIZED: - if(!isDestination) - accessMask = VK_ACCESS_HOST_WRITE_BIT; + if(!is_destination) + access_mask = VK_ACCESS_HOST_WRITE_BIT; else - core::error::report(e_kind::error, "Vulkan : the new layout used in a transition must not be VK_IMAGE_LAYOUT_PREINITIALIZED"); + Error("Vulkan : the new layout used in a transition must not be VK_IMAGE_LAYOUT_PREINITIALIZED"); break; - case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: accessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; break; - case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: accessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; break; - case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: accessMask = VK_ACCESS_MEMORY_READ_BIT; break; + case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: access_mask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; break; + case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: access_mask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; break; + case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: access_mask = VK_ACCESS_MEMORY_READ_BIT; break; - default: core::error::report(e_kind::error, "Vulkan : unexpected image layout"); break; + default: Error("Vulkan : unexpected image layout"); break; } - return accessMask; + return access_mask; } - void Image::create(std::uint32_t width, std::uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, const char* name, bool dedicated_memory) + void Image::Create(std::uint32_t width, std::uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, const char* name, bool dedicated_memory) { - _width = width; - _height = height; - _format = format; - _tiling = tiling; + m_width = width; + m_height = height; + m_format = format; + m_tiling = tiling; - VkImageCreateInfo imageInfo{}; - imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - imageInfo.imageType = VK_IMAGE_TYPE_2D; - imageInfo.extent.width = width; - imageInfo.extent.height = height; - imageInfo.extent.depth = 1; - imageInfo.mipLevels = 1; - imageInfo.arrayLayers = 1; - imageInfo.format = format; - imageInfo.tiling = tiling; - imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - imageInfo.usage = usage; - imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; - imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + VkImageCreateInfo image_info{}; + image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + image_info.imageType = VK_IMAGE_TYPE_2D; + image_info.extent.width = width; + image_info.extent.height = height; + image_info.extent.depth = 1; + image_info.mipLevels = 1; + image_info.arrayLayers = 1; + image_info.format = format; + image_info.tiling = tiling; + image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + image_info.usage = usage; + image_info.samples = VK_SAMPLE_COUNT_1_BIT; + image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; VmaAllocationCreateInfo alloc_info{}; alloc_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; @@ -131,35 +128,35 @@ namespace mlx alloc_info.priority = 1.0f; } - _allocation = Render_Core::get().getAllocator().createImage(&imageInfo, &alloc_info, _image, name); + m_allocation = RenderCore::Get().GetAllocator().CreateImage(&image_info, &alloc_info, m_image, name); #ifdef DEBUG - _name = name; + m_name = name; #endif } - void Image::createImageView(VkImageViewType type, VkImageAspectFlags aspectFlags) noexcept + void Image::CreateImageView(VkImageViewType type, VkImageAspectFlags aspect_flags) noexcept { - VkImageViewCreateInfo viewInfo{}; - viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - viewInfo.image = _image; - viewInfo.viewType = type; - viewInfo.format = _format; - viewInfo.subresourceRange.aspectMask = aspectFlags; - viewInfo.subresourceRange.baseMipLevel = 0; - viewInfo.subresourceRange.levelCount = 1; - viewInfo.subresourceRange.baseArrayLayer = 0; - viewInfo.subresourceRange.layerCount = 1; + VkImageViewCreateInfo view_info{}; + view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + view_info.image = m_image; + view_info.viewType = type; + view_info.format = m_format; + view_info.subresourceRange.aspectMask = aspect_flags; + view_info.subresourceRange.baseMipLevel = 0; + view_info.subresourceRange.levelCount = 1; + view_info.subresourceRange.baseArrayLayer = 0; + view_info.subresourceRange.layerCount = 1; - VkResult res = vkCreateImageView(Render_Core::get().getDevice().get(), &viewInfo, nullptr, &_image_view); + VkResult res = vkCreateImageView(RenderCore::Get().GetDevice().Get(), &view_info, nullptr, &m_image_view); if(res != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Vulkan : failed to create an image view, %s", RCore::verbaliseResultVk(res)); + FatalError("Vulkan : failed to create an image view, %s", VerbaliseVkResult(res)); #ifdef DEBUG else - Render_Core::get().getLayers().setDebugUtilsObjectNameEXT(VK_OBJECT_TYPE_IMAGE_VIEW, (std::uint64_t)_image_view, _name.c_str()); + RenderCore::Get().GetLayers().SetDebugUtilsObjectNameEXT(VK_OBJECT_TYPE_IMAGE_VIEW, (std::uint64_t)m_image_view, m_name.c_str()); #endif } - void Image::createSampler() noexcept + void Image::CreateSampler() noexcept { VkSamplerCreateInfo info{}; info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; @@ -174,94 +171,94 @@ namespace mlx info.anisotropyEnable = VK_FALSE; info.maxAnisotropy = 1.0f; - VkResult res = vkCreateSampler(Render_Core::get().getDevice().get(), &info, nullptr, &_sampler); + VkResult res = vkCreateSampler(RenderCore::Get().GetDevice().Get(), &info, nullptr, &m_sampler); if(res != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Vulkan : failed to create an image sampler, %s", RCore::verbaliseResultVk(res)); + FatalError("Vulkan : failed to create an image sampler, %", VerbaliseVkResult(res)); #ifdef DEBUG else - Render_Core::get().getLayers().setDebugUtilsObjectNameEXT(VK_OBJECT_TYPE_SAMPLER, (std::uint64_t)_sampler, _name.c_str()); + RenderCore::Get().GetLayers().SetDebugUtilsObjectNameEXT(VK_OBJECT_TYPE_SAMPLER, (std::uint64_t)m_sampler, m_name.c_str()); #endif } - void Image::copyFromBuffer(Buffer& buffer) + void Image::CopyFromBuffer(Buffer& buffer) { - CmdBuffer& cmd = Render_Core::get().getSingleTimeCmdBuffer(); - cmd.beginRecord(); + CommandBuffer& cmd = RenderCore::Get().GetSingleTimeCmdBuffer(); + cmd.BeginRecord(); - VkImageLayout layout_save = _layout; - transitionLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &cmd); + VkImageLayout layout_save = m_layout; + TransitionLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &cmd); - cmd.copyBufferToImage(buffer, *this); + cmd.CopyBufferToImage(buffer, *this); - transitionLayout(layout_save, &cmd); + TransitionLayout(layout_save, &cmd); - cmd.endRecord(); - cmd.submitIdle(); + cmd.EndRecord(); + cmd.SubmitIdle(); } - void Image::copyToBuffer(Buffer& buffer) + void Image::CopyToBuffer(Buffer& buffer) { - CmdBuffer& cmd = Render_Core::get().getSingleTimeCmdBuffer(); - cmd.beginRecord(); + CommandBuffer& cmd = RenderCore::Get().GetSingleTimeCmdBuffer(); + cmd.BeginRecord(); - VkImageLayout layout_save = _layout; - transitionLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &cmd); + VkImageLayout layout_save = m_layout; + TransitionLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &cmd); - cmd.copyImagetoBuffer(*this, buffer); + cmd.CopyImagetoBuffer(*this, buffer); - transitionLayout(layout_save, &cmd); + TransitionLayout(layout_save, &cmd); - cmd.endRecord(); - cmd.submitIdle(); + cmd.EndRecord(); + cmd.SubmitIdle(); } - void Image::transitionLayout(VkImageLayout new_layout, CmdBuffer* cmd) + void Image::TransitionLayout(VkImageLayout new_layout, NonOwningPtr cmd) { - if(new_layout == _layout) + if(new_layout == m_layout) return; - bool singleTime = (cmd == nullptr); - if(singleTime) + bool single_time = (cmd == nullptr); + if(single_time) { - cmd = &Render_Core::get().getSingleTimeCmdBuffer(); - cmd->beginRecord(); + cmd = &RenderCore::Get().GetSingleTimeCmdBuffer(); + cmd->BeginRecord(); } - cmd->transitionImageLayout(*this, new_layout); + cmd->TransitionImageLayout(*this, new_layout); - if(singleTime) + if(single_time) { - cmd->endRecord(); - cmd->submitIdle(); + cmd->EndRecord(); + cmd->SubmitIdle(); } - _layout = new_layout; + m_layout = new_layout; } - void Image::destroySampler() noexcept + void Image::DestroySampler() noexcept { - if(_sampler != VK_NULL_HANDLE) - vkDestroySampler(Render_Core::get().getDevice().get(), _sampler, nullptr); - _sampler = VK_NULL_HANDLE; + if(m_sampler != VK_NULL_HANDLE) + vkDestroySampler(RenderCore::Get().GetDevice().Get(), m_sampler, nullptr); + m_sampler = VK_NULL_HANDLE; } - void Image::destroyImageView() noexcept + void Image::DestroyImageView() noexcept { - if(_image_view != VK_NULL_HANDLE) - vkDestroyImageView(Render_Core::get().getDevice().get(), _image_view, nullptr); - _image_view = VK_NULL_HANDLE; + if(m_image_view != VK_NULL_HANDLE) + vkDestroyImageView(RenderCore::Get().GetDevice().Get(), m_image_view, nullptr); + m_image_view = VK_NULL_HANDLE; } - void Image::destroy() noexcept + void Image::Destroy() noexcept { - destroySampler(); - destroyImageView(); + DestroySampler(); + DestroyImageView(); - if(_image != VK_NULL_HANDLE) - Render_Core::get().getAllocator().destroyImage(_allocation, _image); - _image = VK_NULL_HANDLE; + if(m_image != VK_NULL_HANDLE) + RenderCore::Get().GetAllocator().DestroyImage(m_allocation, m_image); + m_image = VK_NULL_HANDLE; } - std::uint32_t formatSize(VkFormat format) + std::uint32_t FormatSize(VkFormat format) { switch(format) { diff --git a/runtime/Sources/Renderer/Images/texture.cpp b/runtime/Sources/Renderer/Images/Texture.cpp similarity index 95% rename from runtime/Sources/Renderer/Images/texture.cpp rename to runtime/Sources/Renderer/Images/Texture.cpp index 5037ac2..420200f 100644 --- a/runtime/Sources/Renderer/Images/texture.cpp +++ b/runtime/Sources/Renderer/Images/Texture.cpp @@ -1,25 +1,23 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* texture.cpp :+: :+: :+: */ +/* Texture.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/03/31 18:03:35 by maldavid #+# #+# */ -/* Updated: 2024/03/25 19:03:04 by maldavid ### ########.fr */ +/* Updated: 2024/04/23 20:59:20 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ #define STB_IMAGE_IMPLEMENTATION #include -#include +#include -#include -#include -#include -#include -#include +#include +#include +#include #ifdef IMAGE_OPTIMIZED #define TILING VK_IMAGE_TILING_OPTIMAL diff --git a/runtime/Sources/Renderer/Images/texture_atlas.cpp b/runtime/Sources/Renderer/Images/TextureAtlas.cpp similarity index 100% rename from runtime/Sources/Renderer/Images/texture_atlas.cpp rename to runtime/Sources/Renderer/Images/TextureAtlas.cpp diff --git a/runtime/Sources/Renderer/Pipelines/pipeline.cpp b/runtime/Sources/Renderer/Pipelines/Pipeline.cpp similarity index 100% rename from runtime/Sources/Renderer/Pipelines/pipeline.cpp rename to runtime/Sources/Renderer/Pipelines/Pipeline.cpp diff --git a/xmake.lua b/xmake.lua index d2d835d..449cb19 100644 --- a/xmake.lua +++ b/xmake.lua @@ -53,9 +53,9 @@ target("mlx") add_options("images_optimized") add_options("force_integrated_gpu") add_options("graphics_memory_dump") - add_includedirs("includes", "src", "third_party") + add_includedirs("runtime/Includes", "runtime/Sources", "third_party") - set_pcxxheader("src/pre_compiled.h") + set_pcxxheader("runtime/Sources/PreCompiled.h") add_defines("MLX_BUILD", "SDL_MAIN_HANDLED")