diff --git a/src/renderer/command/vk_cmd_buffer.cpp b/src/renderer/command/vk_cmd_buffer.cpp index e417508..2c47f76 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: 2023/12/16 18:51:03 by maldavid ### ########.fr */ +/* Updated: 2023/12/23 01:32:02 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -86,27 +86,33 @@ namespace mlx vkCreateFence(device, &fenceCreateInfo, nullptr, &fence); vkResetFences(device, 1, &fence); vkQueueSubmit(Render_Core::get().getQueue().getGraphic(), 1, &submitInfo, fence); + _state = state::submitted; vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX); vkDestroyFence(device, fence, nullptr); - _state = state::submitted; _state = state::ready; } - void CmdBuffer::submit(Semaphore& semaphores) noexcept + void CmdBuffer::submit(Semaphore* semaphores) noexcept { - VkSemaphore signalSemaphores[] = { semaphores.getRenderImageSemaphore() }; - VkSemaphore waitSemaphores[] = { semaphores.getImageSemaphore() }; + std::array signalSemaphores; + std::array waitSemaphores; + + if(semaphores != nullptr) + { + signalSemaphores[0] = semaphores->getRenderImageSemaphore(); + waitSemaphores[0] = semaphores->getImageSemaphore(); + } VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; VkSubmitInfo submitInfo{}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.waitSemaphoreCount = 1; - submitInfo.pWaitSemaphores = waitSemaphores; + submitInfo.waitSemaphoreCount = (semaphores == nullptr ? 0 : waitSemaphores.size()); + submitInfo.pWaitSemaphores = waitSemaphores.data(); submitInfo.pWaitDstStageMask = waitStages; submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &_cmd_buffer; - submitInfo.signalSemaphoreCount = 1; - submitInfo.pSignalSemaphores = signalSemaphores; + submitInfo.signalSemaphoreCount = (semaphores == nullptr ? 0 : signalSemaphores.size()); + submitInfo.pSignalSemaphores = signalSemaphores.data(); if(vkQueueSubmit(Render_Core::get().getQueue().getGraphic(), 1, &submitInfo, _fence.get()) != VK_SUCCESS) core::error::report(e_kind::fatal_error, "Vulkan error : failed to submit draw command buffer"); diff --git a/src/renderer/command/vk_cmd_buffer.h b/src/renderer/command/vk_cmd_buffer.h index f3fe39d..8cc1afb 100644 --- a/src/renderer/command/vk_cmd_buffer.h +++ b/src/renderer/command/vk_cmd_buffer.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/06 18:25:42 by maldavid #+# #+# */ -/* Updated: 2023/12/16 18:44:48 by maldavid ### ########.fr */ +/* Updated: 2023/12/23 01:24:34 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -37,7 +37,7 @@ namespace mlx void destroy() noexcept; void beginRecord(VkCommandBufferUsageFlags usage = 0); - void submit(class Semaphore& semaphores) noexcept; + void submit(class Semaphore* semaphores) noexcept; void submitIdle() noexcept; inline void waitForExecution() noexcept { _fence.waitAndReset(); _state = state::ready; } inline void reset() noexcept { vkResetCommandBuffer(_cmd_buffer, 0); } diff --git a/src/renderer/images/texture.cpp b/src/renderer/images/texture.cpp index 2159df3..d013652 100644 --- a/src/renderer/images/texture.cpp +++ b/src/renderer/images/texture.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/03/31 18:03:35 by maldavid #+# #+# */ -/* Updated: 2023/12/22 23:07:44 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/23 01:52:49 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -34,6 +34,7 @@ namespace mlx Image::create(width, height, format, TILING, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, name, dedicated_memory); Image::createImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT); Image::createSampler(); + transitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); std::vector vertexData = { {{0, 0}, {1.f, 1.f, 1.f, 1.f}, {0.0f, 0.0f}}, @@ -119,12 +120,17 @@ namespace mlx Image::copyFromBuffer(*_buf_map); _has_been_modified = false; } - auto cmd = renderer.getActiveCmdBuffer().get(); + auto cmd = renderer.getActiveCmdBuffer(); + VkImageLayout layout_save = getLayout(); + if(getLayout() != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + transitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, &cmd); _vbo.bind(renderer); _ibo.bind(renderer); glm::vec2 translate(x, y); - vkCmdPushConstants(cmd, renderer.getPipeline().getPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(translate), &translate); - vkCmdDrawIndexed(cmd, static_cast(_ibo.getSize() / sizeof(uint16_t)), 1, 0, 0, 0); + vkCmdPushConstants(cmd.get(), renderer.getPipeline().getPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(translate), &translate); + vkCmdDrawIndexed(cmd.get(), static_cast(_ibo.getSize() / sizeof(uint16_t)), 1, 0, 0, 0); + if(getLayout() != layout_save) + transitionLayout(layout_save, &cmd); } void Texture::destroy() noexcept @@ -147,11 +153,13 @@ namespace mlx core::error::report(e_kind::fatal_error, "Image : file not found '%s'", filename.c_str()); if(stbi_is_hdr(filename.c_str())) core::error::report(e_kind::fatal_error, "Texture : unsupported image format '%s'", filename.c_str()); - data = stbi_load(filename.c_str(), w, h, &channels, 4); + int dummy_w; + int dummy_h; + data = stbi_load(filename.c_str(), (w == nullptr ? &dummy_w : w), (h == nullptr ? &dummy_h : h), &channels, 4); #ifdef DEBUG - texture.create(data, *w, *h, VK_FORMAT_R8G8B8A8_UNORM, filename.c_str()); + texture.create(data, (w == nullptr ? dummy_w : *w), (h == nullptr ? dummy_h : *h), VK_FORMAT_R8G8B8A8_UNORM, filename.c_str()); #else - texture.create(data, *w, *h, VK_FORMAT_R8G8B8A8_UNORM, nullptr); + texture.create(data, (w == nullptr ? dummy_w : *w), (h == nullptr ? dummy_h : *h), VK_FORMAT_R8G8B8A8_UNORM, nullptr); #endif stbi_image_free(data); return texture; diff --git a/src/renderer/images/texture_atlas.cpp b/src/renderer/images/texture_atlas.cpp index be611bc..5a6d9a9 100644 --- a/src/renderer/images/texture_atlas.cpp +++ b/src/renderer/images/texture_atlas.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/07 16:40:09 by maldavid #+# #+# */ -/* Updated: 2023/12/14 16:39:54 by maldavid ### ########.fr */ +/* Updated: 2023/12/22 23:39:38 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,6 +25,7 @@ namespace mlx Image::create(width, height, format, TILING, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, name, dedicated_memory); Image::createImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT); Image::createSampler(); + transitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); if(pixels != nullptr) { diff --git a/src/renderer/images/vk_image.cpp b/src/renderer/images/vk_image.cpp index 54e3ecf..2d31cd5 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: 2023/12/16 17:10:33 by maldavid ### ########.fr */ +/* Updated: 2023/12/22 23:35:07 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -210,18 +210,8 @@ namespace mlx CmdBuffer& cmd = Render_Core::get().getSingleTimeCmdBuffer(); cmd.beginRecord(); - VkImageMemoryBarrier copy_barrier{}; - copy_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - copy_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - copy_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - copy_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - copy_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - copy_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - copy_barrier.image = _image; - copy_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - copy_barrier.subresourceRange.levelCount = 1; - copy_barrier.subresourceRange.layerCount = 1; - vkCmdPipelineBarrier(cmd.get(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, ©_barrier); + VkImageLayout layout_save = _layout; + transitionLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &cmd); VkBufferImageCopy region{}; region.bufferOffset = 0; @@ -236,19 +226,7 @@ namespace mlx vkCmdCopyBufferToImage(cmd.get(), buffer.get(), _image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); - VkImageMemoryBarrier use_barrier{}; - use_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - use_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - use_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - use_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - use_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - use_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - use_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - use_barrier.image = _image; - use_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - use_barrier.subresourceRange.levelCount = 1; - use_barrier.subresourceRange.layerCount = 1; - vkCmdPipelineBarrier(cmd.get(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &use_barrier); + transitionLayout(layout_save, &cmd); cmd.endRecord(); cmd.submitIdle(); @@ -259,18 +237,8 @@ namespace mlx CmdBuffer& cmd = Render_Core::get().getSingleTimeCmdBuffer(); cmd.beginRecord(); - VkImageMemoryBarrier copy_barrier{}; - copy_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - copy_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - copy_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - copy_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - copy_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - copy_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - copy_barrier.image = _image; - copy_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - copy_barrier.subresourceRange.levelCount = 1; - copy_barrier.subresourceRange.layerCount = 1; - vkCmdPipelineBarrier(cmd.get(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, ©_barrier); + VkImageLayout layout_save = _layout; + transitionLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &cmd); VkBufferImageCopy region{}; region.bufferOffset = 0; @@ -285,31 +253,23 @@ namespace mlx vkCmdCopyImageToBuffer(cmd.get(), _image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer.get(), 1, ®ion); - VkImageMemoryBarrier use_barrier{}; - use_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - use_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - use_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - use_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - use_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - use_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - use_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - use_barrier.image = _image; - use_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - use_barrier.subresourceRange.levelCount = 1; - use_barrier.subresourceRange.layerCount = 1; - vkCmdPipelineBarrier(cmd.get(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &use_barrier); + transitionLayout(layout_save, &cmd); cmd.endRecord(); cmd.submitIdle(); } - void Image::transitionLayout(VkImageLayout new_layout) + void Image::transitionLayout(VkImageLayout new_layout, CmdBuffer* cmd) { if(new_layout == _layout) return; - CmdBuffer& cmd = Render_Core::get().getSingleTimeCmdBuffer(); - cmd.beginRecord(); + bool singleTime = (cmd == nullptr); + if(singleTime) + { + cmd = &Render_Core::get().getSingleTimeCmdBuffer(); + cmd->beginRecord(); + } VkImageMemoryBarrier barrier{}; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; @@ -344,10 +304,13 @@ namespace mlx else destinationStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - vkCmdPipelineBarrier(cmd.get(), sourceStage, destinationStage, 0, 0, nullptr, 0, nullptr, 1, &barrier); + vkCmdPipelineBarrier(cmd->get(), sourceStage, destinationStage, 0, 0, nullptr, 0, nullptr, 1, &barrier); - cmd.endRecord(); - cmd.submitIdle(); + if(singleTime) + { + cmd->endRecord(); + cmd->submitIdle(); + } _layout = new_layout; } diff --git a/src/renderer/images/vk_image.h b/src/renderer/images/vk_image.h index 5315190..958df86 100644 --- a/src/renderer/images/vk_image.h +++ b/src/renderer/images/vk_image.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/01/25 11:54:21 by maldavid #+# #+# */ -/* Updated: 2023/12/22 23:02:54 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/22 23:31:02 by kbz_8 ### ########.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); + void transitionLayout(VkImageLayout new_layout, CmdBuffer* cmd = nullptr); virtual void destroy() noexcept; inline VkImage get() noexcept { return _image; } diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index db34449..7fbe199 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/12/18 17:25:16 by maldavid #+# #+# */ -/* Updated: 2023/12/22 23:16:10 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/23 01:28:03 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -74,8 +74,6 @@ namespace mlx auto device = Render_Core::get().getDevice().get(); _cmd.getCmdBuffer(_current_frame_index).waitForExecution(); - _cmd.getCmdBuffer(_current_frame_index).reset(); - if(_render_target == nullptr) { VkResult result = vkAcquireNextImageKHR(device, _swapchain(), UINT64_MAX, _semaphores[_current_frame_index].getImageSemaphore(), VK_NULL_HANDLE, &_image_index); @@ -91,6 +89,7 @@ namespace mlx else _image_index = 0; + _cmd.getCmdBuffer(_current_frame_index).reset(); _cmd.getCmdBuffer(_current_frame_index).beginRecord(); auto& fb = _framebuffers[_image_index]; _pass.begin(getActiveCmdBuffer(), fb); @@ -121,7 +120,7 @@ namespace mlx if(_render_target == nullptr) { - _cmd.getCmdBuffer(_current_frame_index).submit(_semaphores[_current_frame_index]); + _cmd.getCmdBuffer(_current_frame_index).submit(&_semaphores[_current_frame_index]); VkSwapchainKHR swapchain = _swapchain(); VkSemaphore signalSemaphores[] = { _semaphores[_current_frame_index].getRenderImageSemaphore() }; @@ -145,7 +144,7 @@ namespace mlx core::error::report(e_kind::fatal_error, "Vulkan error : failed to present swap chain image"); } else - _cmd.getCmdBuffer(_current_frame_index).submitIdle(); + _cmd.getCmdBuffer(_current_frame_index).submit(nullptr); _current_frame_index = (_current_frame_index + 1) % MAX_FRAMES_IN_FLIGHT; } @@ -162,12 +161,13 @@ namespace mlx _desc_pool.destroy(); _pass.destroy(); if(_render_target == nullptr) + { _swapchain.destroy(); + _surface.destroy(); + } for(auto& fb : _framebuffers) fb.destroy(); for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) _semaphores[i].destroy(); - if(_render_target == nullptr) - _surface.destroy(); } }