From d9a7f337bacc3e6be38c832a7c05625875711592 Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Fri, 5 Jan 2024 23:13:35 +0100 Subject: [PATCH] working on cmd resources management --- example/main.c | 2 +- includes/mlx.h | 9 +- src/core/errors.cpp | 2 +- .../command/single_time_cmd_manager.cpp | 4 +- .../command/single_time_cmd_manager.h | 4 +- src/renderer/command/vk_cmd_buffer.cpp | 121 +++++++++++++++++- src/renderer/command/vk_cmd_buffer.h | 6 +- src/renderer/core/cmd_resource.h | 16 ++- src/renderer/images/vk_image.cpp | 63 +-------- src/renderer/images/vk_image.h | 7 +- 10 files changed, 162 insertions(+), 72 deletions(-) diff --git a/example/main.c b/example/main.c index 3f55325..7d09156 100644 --- a/example/main.c +++ b/example/main.c @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 17:55:21 by maldavid #+# #+# */ -/* Updated: 2024/01/03 12:29:31 by maldavid ### ########.fr */ +/* Updated: 2024/01/04 12:44:58 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/includes/mlx.h b/includes/mlx.h index 14f4453..733f237 100644 --- a/includes/mlx.h +++ b/includes/mlx.h @@ -6,11 +6,12 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 16:56:35 by maldavid #+# #+# */ -/* Updated: 2023/12/27 17:19:50 by maldavid ### ########.fr */ +/* Updated: 2024/01/05 19:53:13 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ // MacroLibX official repo https://github.com/seekrs/MacroLibX +// MacroLibX official website https://macrolibx.kbz8.me/ #ifndef __MACRO_LIB_X_H__ #define __MACRO_LIB_X_H__ @@ -147,10 +148,10 @@ MLX_API int mlx_on_event(void* mlx, void* win, mlx_event_type event, int (*f)(in * @param win Internal window * @param x X coordinate * @param y Y coordinate - * @param color Color of the pixel (coded on 3 bytes in an int, 0x00RRGGBB) + * @param color Color of the pixel (coded on 4 bytes in an int, 0xAARRGGBB) * * Note : If your're reading pixel colors from an image, don't forget to shift them - * one byte to the right as image pixels are encoded as 0xRRGGBBAA and pixel put takes 0x00RRGGBB. + * one byte to the right as image pixels are encoded as 0xRRGGBBAA and pixel put takes 0xAARRGGBB. * * @return (int) Always return 0, made this to copy the behaviour of the original MLX */ @@ -283,7 +284,7 @@ MLX_API void* mlx_bmp_file_to_image(void* mlx, char* filename, int* width, int* * @param win Internal window * @param x X coordinate * @param y Y coordinate - * @param color Color of the pixel (coded on 3 bytes in an int, 0x00RRGGBB) + * @param color Color of the pixel (coded on 4 bytes in an int, 0xAARRGGBB) * @param str Text to put * * @return (int) Always return 0, made this to copy the behaviour of the original MLX diff --git a/src/core/errors.cpp b/src/core/errors.cpp index 0fb675b..63aa607 100644 --- a/src/core/errors.cpp +++ b/src/core/errors.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 17:48:06 by maldavid #+# #+# */ -/* Updated: 2023/11/14 07:14:57 by maldavid ### ########.fr */ +/* Updated: 2024/01/05 20:41:17 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/renderer/command/single_time_cmd_manager.cpp b/src/renderer/command/single_time_cmd_manager.cpp index 2feb498..e668676 100644 --- a/src/renderer/command/single_time_cmd_manager.cpp +++ b/src/renderer/command/single_time_cmd_manager.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/12/15 19:57:49 by maldavid #+# #+# */ -/* Updated: 2023/12/17 20:10:25 by maldavid ### ########.fr */ +/* Updated: 2024/01/05 20:29:01 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -51,4 +51,6 @@ namespace mlx }); _pool.destroy(); } + + SingleTimeCmdManager::~SingleTimeCmdManager() {} } diff --git a/src/renderer/command/single_time_cmd_manager.h b/src/renderer/command/single_time_cmd_manager.h index ebba883..dcbb0f8 100644 --- a/src/renderer/command/single_time_cmd_manager.h +++ b/src/renderer/command/single_time_cmd_manager.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/12/15 18:25:57 by maldavid #+# #+# */ -/* Updated: 2023/12/17 17:36:18 by maldavid ### ########.fr */ +/* Updated: 2024/01/05 20:28:41 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -32,7 +32,7 @@ namespace mlx inline CmdPool& getCmdPool() noexcept { return _pool; } CmdBuffer& getCmdBuffer() noexcept; - ~SingleTimeCmdManager() = default; + ~SingleTimeCmdManager(); inline static constexpr const uint8_t MIN_POOL_SIZE = 8; diff --git a/src/renderer/command/vk_cmd_buffer.cpp b/src/renderer/command/vk_cmd_buffer.cpp index b262761..5b38563 100644 --- a/src/renderer/command/vk_cmd_buffer.cpp +++ b/src/renderer/command/vk_cmd_buffer.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/06 18:26:06 by maldavid #+# #+# */ -/* Updated: 2024/01/04 12:27:19 by maldavid ### ########.fr */ +/* Updated: 2024/01/05 23:06:04 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,6 +15,7 @@ #include #include #include +#include namespace mlx { @@ -73,6 +74,124 @@ namespace mlx buffer.recordedInCmdBuffer(); } + void CmdBuffer::bindIndexBuffer(Buffer& buffer) const noexcept + { + if(!isRecording()) + { + core::error::report(e_kind::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); + buffer.recordedInCmdBuffer(); + } + + void CmdBuffer::copyBuffer(Buffer& dst, Buffer& src) const noexcept + { + if(!isRecording()) + { + core::error::report(e_kind::warning, "Vulkan : trying to do a buffer to buffer copy in a non recording command buffer"); + return; + } + VkBufferCopy copyRegion{}; + copyRegion.size = src.getSize(); + vkCmdCopyBuffer(_cmd_buffer, src.get(), dst.get(), 1, ©Region); + dst.recordedInCmdBuffer(); + src.recordedInCmdBuffer(); + } + + void CmdBuffer::copyBufferToImage(Buffer& buffer, Image& image) const noexcept + { + if(!isRecording()) + { + core::error::report(e_kind::warning, "Vulkan : trying to do a buffer to image copy in a non recording command buffer"); + return; + } + VkBufferImageCopy region{}; + region.bufferOffset = 0; + region.bufferRowLength = 0; + region.bufferImageHeight = 0; + region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + region.imageSubresource.mipLevel = 0; + region.imageSubresource.baseArrayLayer = 0; + region.imageSubresource.layerCount = 1; + region.imageOffset = { 0, 0, 0 }; + region.imageExtent = { image.getWidth(), image.getHeight(), 1 }; + + vkCmdCopyBufferToImage(_cmd_buffer, buffer.get(), image.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + + image.recordedInCmdBuffer(); + buffer.recordedInCmdBuffer(); + } + + void CmdBuffer::copyImagetoBuffer(Image& image, Buffer& buffer) const noexcept + { + if(!isRecording()) + { + core::error::report(e_kind::warning, "Vulkan : trying to do an image to buffer copy in a non recording command buffer"); + return; + } + VkBufferImageCopy region{}; + region.bufferOffset = 0; + region.bufferRowLength = 0; + region.bufferImageHeight = 0; + region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + region.imageSubresource.mipLevel = 0; + region.imageSubresource.baseArrayLayer = 0; + region.imageSubresource.layerCount = 1; + region.imageOffset = { 0, 0, 0 }; + region.imageExtent = { image.getWidth(), image.getHeight(), 1 }; + + vkCmdCopyImageToBuffer(_cmd_buffer, image.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer.get(), 1, ®ion); + + image.recordedInCmdBuffer(); + buffer.recordedInCmdBuffer(); + } + + void CmdBuffer::transitionImageLayout(Image& image, VkImageLayout new_layout) const noexcept + { + if(!isRecording()) + { + core::error::report(e_kind::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.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.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.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; + + VkPipelineStageFlags sourceStage = 0; + if(barrier.oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) + sourceStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + else if(barrier.srcAccessMask != 0) + sourceStage = 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; + + VkPipelineStageFlags destinationStage = 0; + if(barrier.newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) + destinationStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + else if(barrier.dstAccessMask != 0) + destinationStage = 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; + + vkCmdPipelineBarrier(_cmd_buffer, sourceStage, destinationStage, 0, 0, nullptr, 0, nullptr, 1, &barrier); + image.recordedInCmdBuffer(); + } + void CmdBuffer::endRecord() { if(!isInit()) diff --git a/src/renderer/command/vk_cmd_buffer.h b/src/renderer/command/vk_cmd_buffer.h index 93fd55f..421890c 100644 --- a/src/renderer/command/vk_cmd_buffer.h +++ b/src/renderer/command/vk_cmd_buffer.h @@ -6,16 +6,18 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/06 18:25:42 by maldavid #+# #+# */ -/* Updated: 2024/01/03 15:27:20 by maldavid ### ########.fr */ +/* Updated: 2024/01/05 23:10:01 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef __MLX_VK_CMD_BUFFER__ #define __MLX_VK_CMD_BUFFER__ +#include #include #include #include +#include namespace mlx { @@ -57,6 +59,7 @@ namespace mlx void copyBuffer(Buffer& dst, Buffer& src) const noexcept; void copyBufferToImage(Buffer& buffer, Image& image) const noexcept; void copyImagetoBuffer(Image& image, Buffer& buffer) const noexcept; + void transitionImageLayout(Image& image, VkImageLayout new_layout) const noexcept; inline bool isInit() const noexcept { return _state != state::uninit; } inline bool isReadyToBeUsed() const noexcept { return _state == state::ready; } @@ -69,6 +72,7 @@ namespace mlx inline Fence& getFence() noexcept { return _fence; } private: + std::unordered_set _resources; Fence _fence; VkCommandBuffer _cmd_buffer = VK_NULL_HANDLE; class CmdPool* _pool = nullptr; diff --git a/src/renderer/core/cmd_resource.h b/src/renderer/core/cmd_resource.h index 8abd63b..67db160 100644 --- a/src/renderer/core/cmd_resource.h +++ b/src/renderer/core/cmd_resource.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/12/16 20:44:29 by maldavid #+# #+# */ -/* Updated: 2023/12/17 17:10:03 by maldavid ### ########.fr */ +/* Updated: 2024/01/05 23:12:45 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -47,16 +47,30 @@ namespace mlx else _destroy_required = true; } + inline uint64_t getUUID() const noexcept { return _uuid; } virtual ~CmdResource() = default; private: void realDestroy(); private: + uint64_t _uuid = 0; state _state = state::out_cmd_buffer; func::function _destroyer; bool _destroy_required = false; }; } +namespace std +{ + template <> + struct hash + { + std::size_t operator()(const mlx::CmdResource& res) const noexcept + { + return res.getUUID(); + } + }; +} + #endif diff --git a/src/renderer/images/vk_image.cpp b/src/renderer/images/vk_image.cpp index a6703c2..79f806d 100644 --- a/src/renderer/images/vk_image.cpp +++ b/src/renderer/images/vk_image.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/01/25 11:59:07 by maldavid #+# #+# */ -/* Updated: 2024/01/03 13:16:21 by maldavid ### ########.fr */ +/* Updated: 2024/01/05 23:08:47 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -225,18 +225,7 @@ namespace mlx VkImageLayout layout_save = _layout; transitionLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &cmd); - VkBufferImageCopy region{}; - region.bufferOffset = 0; - region.bufferRowLength = 0; - region.bufferImageHeight = 0; - region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - region.imageSubresource.mipLevel = 0; - region.imageSubresource.baseArrayLayer = 0; - region.imageSubresource.layerCount = 1; - region.imageOffset = { 0, 0, 0 }; - region.imageExtent = { _width, _height, 1 }; - - vkCmdCopyBufferToImage(cmd.get(), buffer.get(), _image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + cmd.copyBufferToImage(buffer, *this); transitionLayout(layout_save, &cmd); @@ -252,18 +241,7 @@ namespace mlx VkImageLayout layout_save = _layout; transitionLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &cmd); - VkBufferImageCopy region{}; - region.bufferOffset = 0; - region.bufferRowLength = 0; - region.bufferImageHeight = 0; - region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - region.imageSubresource.mipLevel = 0; - region.imageSubresource.baseArrayLayer = 0; - region.imageSubresource.layerCount = 1; - region.imageOffset = { 0, 0, 0 }; - region.imageExtent = { _width, _height, 1 }; - - vkCmdCopyImageToBuffer(cmd.get(), _image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer.get(), 1, ®ion); + cmd.copyImagetoBuffer(*this, buffer); transitionLayout(layout_save, &cmd); @@ -283,40 +261,7 @@ namespace mlx cmd->beginRecord(); } - VkImageMemoryBarrier barrier{}; - barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - barrier.oldLayout = _layout; - barrier.newLayout = new_layout; - barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - barrier.image = _image; - barrier.subresourceRange.aspectMask = isDepthFormat(_format) ? 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(_layout, false); - barrier.dstAccessMask = layoutToAccessMask(new_layout, true); - if(isStencilFormat(_format)) - barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; - - VkPipelineStageFlags sourceStage = 0; - if(barrier.oldLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) - sourceStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - else if(barrier.srcAccessMask != 0) - sourceStage = 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; - - VkPipelineStageFlags destinationStage = 0; - if(barrier.newLayout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) - destinationStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - else if(barrier.dstAccessMask != 0) - destinationStage = 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; - - vkCmdPipelineBarrier(cmd->get(), sourceStage, destinationStage, 0, 0, nullptr, 0, nullptr, 1, &barrier); + cmd->transitionImageLayout(*this, new_layout); if(singleTime) { diff --git a/src/renderer/images/vk_image.h b/src/renderer/images/vk_image.h index 7cd4d65..3349112 100644 --- a/src/renderer/images/vk_image.h +++ b/src/renderer/images/vk_image.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/01/25 11:54:21 by maldavid #+# #+# */ -/* Updated: 2024/01/03 15:28:07 by maldavid ### ########.fr */ +/* Updated: 2024/01/05 22:36:58 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,6 +25,11 @@ namespace mlx { uint32_t formatSize(VkFormat format); + bool isStencilFormat(VkFormat format); + bool isDepthFormat(VkFormat format); + VkFormat bitsToFormat(uint32_t bits); + VkPipelineStageFlags layoutToAccessMask(VkImageLayout layout, bool isDestination); + VkPipelineStageFlags accessFlagsToPipelineStage(VkAccessFlags accessFlags, VkPipelineStageFlags stageFlags); class Image : public CmdResource {