adding frame capture feature (#21)

This commit is contained in:
kbz_8
2023-12-25 16:18:42 +01:00
committed by GitHub
23 changed files with 246 additions and 188 deletions

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/04 22:10:52 by maldavid #+# #+# */ /* Created: 2022/10/04 22:10:52 by maldavid #+# #+# */
/* Updated: 2023/12/21 00:17:54 by maldavid ### ########.fr */ /* Updated: 2023/12/24 08:56:33 by kbz_8 ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -37,14 +37,12 @@ namespace mlx::core
while(_in->is_running()) while(_in->is_running())
{ {
_in->update(); _in->update();
for(auto& gs : _graphics)
gs->beginRender();
if(_loop_hook) if(_loop_hook)
_loop_hook(_param); _loop_hook(_param);
for(auto& gs : _graphics) for(auto& gs : _graphics)
gs->endRender(); gs->render();
} }
} }

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/04 21:49:46 by maldavid #+# #+# */ /* Created: 2022/10/04 21:49:46 by maldavid #+# #+# */
/* Updated: 2023/12/11 19:46:49 by kbz_8 ### ########.fr */ /* Updated: 2023/12/22 21:04:48 by kbz_8 ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -40,7 +40,7 @@ namespace mlx::core
inline void getScreenSize(int* w, int* h) noexcept; inline void getScreenSize(int* w, int* h) noexcept;
inline void* newGraphicsSuport(std::size_t w, std::size_t h, std::string title); inline void* newGraphicsSuport(std::size_t w, std::size_t h, const char* title);
inline void clearGraphicsSupport(void* win); inline void clearGraphicsSupport(void* win);
inline void destroyGraphicsSupport(void* win); inline void destroyGraphicsSupport(void* win);

View File

@@ -54,10 +54,19 @@ namespace mlx::core
*h = DM.h; *h = DM.h;
} }
void* Application::newGraphicsSuport(std::size_t w, std::size_t h, std::string title) void* Application::newGraphicsSuport(std::size_t w, std::size_t h, const char* title)
{ {
_graphics.emplace_back(std::make_unique<GraphicsSupport>(w, h, title, _graphics.size())); auto it = std::find_if(_textures.begin(), _textures.end(), [=](const Texture& texture)
_in->addWindow(_graphics.back()->getWindow()); {
return &texture == reinterpret_cast<Texture*>(const_cast<char*>(title));
});
if(it != _textures.end())
_graphics.emplace_back(std::make_unique<GraphicsSupport>(w, h, reinterpret_cast<Texture*>(const_cast<char*>(title)), _graphics.size()));
else
{
_graphics.emplace_back(std::make_unique<GraphicsSupport>(w, h, title, _graphics.size()));
_in->addWindow(_graphics.back()->getWindow());
}
return static_cast<void*>(&_graphics.back()->getID()); return static_cast<void*>(&_graphics.back()->getID());
} }

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/02 15:13:55 by maldavid #+# #+# */ /* Created: 2023/04/02 15:13:55 by maldavid #+# #+# */
/* Updated: 2023/12/15 21:04:50 by maldavid ### ########.fr */ /* Updated: 2023/12/24 09:39:45 by kbz_8 ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -14,20 +14,40 @@
namespace mlx namespace mlx
{ {
GraphicsSupport::GraphicsSupport(std::size_t w, std::size_t h, const std::string& title, int id) : GraphicsSupport::GraphicsSupport(std::size_t w, std::size_t h, Texture* render_target, int id) :
_window(std::make_shared<MLX_Window>(w, h, title)), _window(nullptr),
_text_put_pipeline(std::make_unique<TextPutPipeline>()), _text_put_pipeline(std::make_unique<TextPutPipeline>()),
_renderer(std::make_unique<Renderer>()), _renderer(std::make_unique<Renderer>()),
_width(w),
_height(h),
_id(id) _id(id)
{ {
_renderer->setWindow(_window.get()); _renderer->setWindow(nullptr);
_renderer->init(); _renderer->init(render_target);
_pixel_put_pipeline.init(w, h, *_renderer); _pixel_put_pipeline.init(w, h, *_renderer);
_text_put_pipeline->init(_renderer.get()); _text_put_pipeline->init(_renderer.get());
} }
void GraphicsSupport::endRender() noexcept GraphicsSupport::GraphicsSupport(std::size_t w, std::size_t h, std::string title, int id) :
_window(std::make_shared<MLX_Window>(w, h, title)),
_text_put_pipeline(std::make_unique<TextPutPipeline>()),
_renderer(std::make_unique<Renderer>()),
_width(w),
_height(h),
_id(id)
{ {
_renderer->setWindow(_window.get());
_renderer->init(nullptr);
_pixel_put_pipeline.init(w, h, *_renderer);
_text_put_pipeline->init(_renderer.get());
}
void GraphicsSupport::render() noexcept
{
if(!_renderer->beginFrame())
return;
_proj = glm::ortho<float>(0, _width, 0, _height);
_renderer->getUniformBuffer()->setData(sizeof(_proj), &_proj);
auto cmd_buff = _renderer->getActiveCmdBuffer().get(); auto cmd_buff = _renderer->getActiveCmdBuffer().get();
static std::array<VkDescriptorSet, 2> sets = { static std::array<VkDescriptorSet, 2> sets = {
@@ -41,6 +61,8 @@ namespace mlx
continue; continue;
if(data.texture->getSet() == VK_NULL_HANDLE) if(data.texture->getSet() == VK_NULL_HANDLE)
data.texture->setDescriptor(_renderer->getFragDescriptorSet().duplicate()); data.texture->setDescriptor(_renderer->getFragDescriptorSet().duplicate());
if(data.texture->getLayout() != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
data.texture->transitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
if(!data.texture->hasBeenUpdated()) if(!data.texture->hasBeenUpdated())
data.texture->updateSet(0); data.texture->updateSet(0);
sets[1] = data.texture->getSet(); sets[1] = data.texture->getSet();
@@ -76,6 +98,7 @@ namespace mlx
_text_put_pipeline->destroy(); _text_put_pipeline->destroy();
_pixel_put_pipeline.destroy(); _pixel_put_pipeline.destroy();
_renderer->destroy(); _renderer->destroy();
_window->destroy(); if(_window)
_window->destroy();
} }
} }

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/02 14:49:49 by maldavid #+# #+# */ /* Created: 2023/04/02 14:49:49 by maldavid #+# #+# */
/* Updated: 2023/12/11 19:47:03 by kbz_8 ### ########.fr */ /* Updated: 2023/12/24 08:56:14 by kbz_8 ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -33,13 +33,13 @@ namespace mlx
class GraphicsSupport : public non_copyable class GraphicsSupport : public non_copyable
{ {
public: public:
GraphicsSupport(std::size_t w, std::size_t h, const std::string& title, int id); GraphicsSupport(std::size_t w, std::size_t h, Texture* render_target, int id);
GraphicsSupport(std::size_t w, std::size_t h, std::string title, int id);
inline int& getID() noexcept; inline int& getID() noexcept;
inline std::shared_ptr<MLX_Window> getWindow(); inline std::shared_ptr<MLX_Window> getWindow();
inline void beginRender() noexcept; void render() noexcept;
void endRender() noexcept;
inline void clearRenderData() noexcept; inline void clearRenderData() noexcept;
inline void pixelPut(int x, int y, uint32_t color) noexcept; inline void pixelPut(int x, int y, uint32_t color) noexcept;
@@ -56,6 +56,8 @@ namespace mlx
std::shared_ptr<MLX_Window> _window; std::shared_ptr<MLX_Window> _window;
std::unique_ptr<TextPutPipeline> _text_put_pipeline; // unique_ptr because of the size of the class std::unique_ptr<TextPutPipeline> _text_put_pipeline; // unique_ptr because of the size of the class
std::unique_ptr<Renderer> _renderer; std::unique_ptr<Renderer> _renderer;
std::size_t _width = 0;
std::size_t _height = 0;
int _id; int _id;
}; };
} }

View File

@@ -19,14 +19,6 @@ namespace mlx
int& GraphicsSupport::getID() noexcept { return _id; } int& GraphicsSupport::getID() noexcept { return _id; }
std::shared_ptr<MLX_Window> GraphicsSupport::getWindow() { return _window; } std::shared_ptr<MLX_Window> GraphicsSupport::getWindow() { return _window; }
void GraphicsSupport::beginRender() noexcept
{
if(!_renderer->beginFrame())
return;
_proj = glm::ortho<float>(0, _window->getWidth(), 0, _window->getHeight());
_renderer->getUniformBuffer()->setData(sizeof(_proj), &_proj);
}
void GraphicsSupport::clearRenderData() noexcept void GraphicsSupport::clearRenderData() noexcept
{ {
_textures_to_render.clear(); _textures_to_render.clear();

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:26:06 by maldavid #+# #+# */ /* Created: 2022/10/06 18:26:06 by maldavid #+# #+# */
/* Updated: 2023/12/16 18:51:03 by maldavid ### ########.fr */ /* Updated: 2023/12/24 12:58:36 by kbz_8 ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -85,28 +85,40 @@ namespace mlx
VkFence fence; VkFence fence;
vkCreateFence(device, &fenceCreateInfo, nullptr, &fence); vkCreateFence(device, &fenceCreateInfo, nullptr, &fence);
vkResetFences(device, 1, &fence); vkResetFences(device, 1, &fence);
vkQueueSubmit(Render_Core::get().getQueue().getGraphic(), 1, &submitInfo, fence); if(vkQueueSubmit(Render_Core::get().getQueue().getGraphic(), 1, &submitInfo, fence) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan error : failed to submit a single time command buffer");
_state = state::submitted;
vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX); vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX);
vkDestroyFence(device, fence, nullptr); vkDestroyFence(device, fence, nullptr);
_state = state::submitted;
_state = state::ready; _state = state::ready;
} }
void CmdBuffer::submit(Semaphore& semaphores) noexcept void CmdBuffer::submit(Semaphore* semaphores) noexcept
{ {
VkSemaphore signalSemaphores[] = { semaphores.getRenderImageSemaphore() }; std::array<VkSemaphore, 1> signalSemaphores;
VkSemaphore waitSemaphores[] = { semaphores.getImageSemaphore() }; std::array<VkSemaphore, 1> waitSemaphores;
if(semaphores != nullptr)
{
signalSemaphores[0] = semaphores->getRenderImageSemaphore();
waitSemaphores[0] = semaphores->getImageSemaphore();
}
else
{
signalSemaphores[0] = nullptr;
waitSemaphores[0] = nullptr;
}
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
VkSubmitInfo submitInfo{}; VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.waitSemaphoreCount = 1; submitInfo.waitSemaphoreCount = (semaphores == nullptr ? 0 : waitSemaphores.size());
submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitSemaphores = waitSemaphores.data();
submitInfo.pWaitDstStageMask = waitStages; submitInfo.pWaitDstStageMask = waitStages;
submitInfo.commandBufferCount = 1; submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &_cmd_buffer; submitInfo.pCommandBuffers = &_cmd_buffer;
submitInfo.signalSemaphoreCount = 1; submitInfo.signalSemaphoreCount = (semaphores == nullptr ? 0 : signalSemaphores.size());
submitInfo.pSignalSemaphores = signalSemaphores; submitInfo.pSignalSemaphores = signalSemaphores.data();
if(vkQueueSubmit(Render_Core::get().getQueue().getGraphic(), 1, &submitInfo, _fence.get()) != VK_SUCCESS) 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"); core::error::report(e_kind::fatal_error, "Vulkan error : failed to submit draw command buffer");

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:25:42 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 destroy() noexcept;
void beginRecord(VkCommandBufferUsageFlags usage = 0); void beginRecord(VkCommandBufferUsageFlags usage = 0);
void submit(class Semaphore& semaphores) noexcept; void submit(class Semaphore* semaphores) noexcept;
void submitIdle() noexcept; void submitIdle() noexcept;
inline void waitForExecution() noexcept { _fence.waitAndReset(); _state = state::ready; } inline void waitForExecution() noexcept { _fence.waitAndReset(); _state = state::ready; }
inline void reset() noexcept { vkResetCommandBuffer(_cmd_buffer, 0); } inline void reset() noexcept { vkResetCommandBuffer(_cmd_buffer, 0); }

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/01/23 18:40:44 by maldavid #+# #+# */ /* Created: 2023/01/23 18:40:44 by maldavid #+# #+# */
/* Updated: 2023/12/14 16:45:11 by maldavid ### ########.fr */ /* Updated: 2023/12/24 09:37:55 by kbz_8 ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -15,6 +15,7 @@
#include "vk_descriptor_set_layout.h" #include "vk_descriptor_set_layout.h"
#include <renderer/buffers/vk_ubo.h> #include <renderer/buffers/vk_ubo.h>
#include <renderer/renderer.h> #include <renderer/renderer.h>
#include <renderer/images/vk_image.h>
namespace mlx namespace mlx
{ {
@@ -66,14 +67,14 @@ namespace mlx
} }
} }
void DescriptorSet::writeDescriptor(int binding, VkImageView view, VkSampler sampler) const noexcept void DescriptorSet::writeDescriptor(int binding, const Image& image) const noexcept
{ {
auto device = Render_Core::get().getDevice().get(); auto device = Render_Core::get().getDevice().get();
VkDescriptorImageInfo imageInfo{}; VkDescriptorImageInfo imageInfo{};
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; imageInfo.imageLayout = image.getLayout();
imageInfo.imageView = view; imageInfo.imageView = image.getImageView();
imageInfo.sampler = sampler; imageInfo.sampler = image.getSampler();
VkWriteDescriptorSet descriptorWrite{}; VkWriteDescriptorSet descriptorWrite{};
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/01/23 18:39:36 by maldavid #+# #+# */ /* Created: 2023/01/23 18:39:36 by maldavid #+# #+# */
/* Updated: 2023/12/14 17:12:49 by maldavid ### ########.fr */ /* Updated: 2023/12/23 18:47:49 by kbz_8 ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -26,7 +26,7 @@ namespace mlx
void init(class Renderer* renderer, class DescriptorPool* pool, class DescriptorSetLayout* layout); void init(class Renderer* renderer, class DescriptorPool* pool, class DescriptorSetLayout* layout);
void writeDescriptor(int binding, class UBO* ubo) const noexcept; void writeDescriptor(int binding, class UBO* ubo) const noexcept;
void writeDescriptor(int binding, VkImageView view, VkSampler sampler) const noexcept; void writeDescriptor(int binding, const class Image& image) const noexcept;
inline bool isInit() const noexcept { return _pool != nullptr && _renderer != nullptr; } inline bool isInit() const noexcept { return _pool != nullptr && _renderer != nullptr; }

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/03/31 18:03:35 by maldavid #+# #+# */ /* Created: 2023/03/31 18:03:35 by maldavid #+# #+# */
/* Updated: 2023/12/10 22:46:08 by kbz_8 ### ########.fr */ /* Updated: 2023/12/23 18:49:53 by kbz_8 ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -31,9 +31,10 @@ namespace mlx
{ {
void Texture::create(uint8_t* pixels, uint32_t width, uint32_t height, VkFormat format, const char* name, bool dedicated_memory) void Texture::create(uint8_t* pixels, uint32_t width, uint32_t height, VkFormat format, const char* name, bool dedicated_memory)
{ {
Image::create(width, height, format, TILING, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, name, dedicated_memory); Image::create(width, height, format, TILING, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, name, dedicated_memory);
Image::createImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT); Image::createImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT);
Image::createSampler(); Image::createSampler();
transitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
std::vector<Vertex> vertexData = { std::vector<Vertex> vertexData = {
{{0, 0}, {1.f, 1.f, 1.f, 1.f}, {0.0f, 0.0f}}, {{0, 0}, {1.f, 1.f, 1.f, 1.f}, {0.0f, 0.0f}},
@@ -119,12 +120,12 @@ namespace mlx
Image::copyFromBuffer(*_buf_map); Image::copyFromBuffer(*_buf_map);
_has_been_modified = false; _has_been_modified = false;
} }
auto cmd = renderer.getActiveCmdBuffer().get(); auto cmd = renderer.getActiveCmdBuffer();
_vbo.bind(renderer); _vbo.bind(renderer);
_ibo.bind(renderer); _ibo.bind(renderer);
glm::vec2 translate(x, y); glm::vec2 translate(x, y);
vkCmdPushConstants(cmd, renderer.getPipeline().getPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(translate), &translate); vkCmdPushConstants(cmd.get(), renderer.getPipeline().getPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(translate), &translate);
vkCmdDrawIndexed(cmd, static_cast<uint32_t>(_ibo.getSize() / sizeof(uint16_t)), 1, 0, 0, 0); vkCmdDrawIndexed(cmd.get(), static_cast<uint32_t>(_ibo.getSize() / sizeof(uint16_t)), 1, 0, 0, 0);
} }
void Texture::destroy() noexcept void Texture::destroy() noexcept
@@ -147,11 +148,13 @@ namespace mlx
core::error::report(e_kind::fatal_error, "Image : file not found '%s'", filename.c_str()); core::error::report(e_kind::fatal_error, "Image : file not found '%s'", filename.c_str());
if(stbi_is_hdr(filename.c_str())) if(stbi_is_hdr(filename.c_str()))
core::error::report(e_kind::fatal_error, "Texture : unsupported image format '%s'", filename.c_str()); 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 #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 #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 #endif
stbi_image_free(data); stbi_image_free(data);
return texture; return texture;

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/03/08 02:24:58 by maldavid #+# #+# */ /* Created: 2023/03/08 02:24:58 by maldavid #+# #+# */
/* Updated: 2023/12/14 14:37:08 by maldavid ### ########.fr */ /* Updated: 2023/12/23 18:49:12 by kbz_8 ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -40,7 +40,7 @@ namespace mlx
inline void setDescriptor(DescriptorSet set) noexcept { _set = std::move(set); } inline void setDescriptor(DescriptorSet set) noexcept { _set = std::move(set); }
inline VkDescriptorSet getSet() noexcept { return _set.isInit() ? _set.get() : VK_NULL_HANDLE; } inline VkDescriptorSet getSet() noexcept { return _set.isInit() ? _set.get() : VK_NULL_HANDLE; }
inline void updateSet(int binding) noexcept { _set.writeDescriptor(binding, getImageView(), getSampler()); _has_been_updated = true; } inline void updateSet(int binding) noexcept { _set.writeDescriptor(binding, *this); _has_been_updated = true; }
inline bool hasBeenUpdated() const noexcept { return _has_been_updated; } inline bool hasBeenUpdated() const noexcept { return _has_been_updated; }
inline constexpr void resetUpdate() noexcept { _has_been_updated = false; } inline constexpr void resetUpdate() noexcept { _has_been_updated = false; }

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/07 16:40:09 by maldavid #+# #+# */ /* Created: 2023/04/07 16:40:09 by maldavid #+# #+# */
/* Updated: 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::create(width, height, format, TILING, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, name, dedicated_memory);
Image::createImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT); Image::createImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT);
Image::createSampler(); Image::createSampler();
transitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
if(pixels != nullptr) if(pixels != nullptr)
{ {

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/07 16:36:33 by maldavid #+# #+# */ /* Created: 2023/04/07 16:36:33 by maldavid #+# #+# */
/* Updated: 2023/12/14 17:12:54 by maldavid ### ########.fr */ /* Updated: 2023/12/23 18:49:25 by kbz_8 ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -31,7 +31,7 @@ namespace mlx
inline void setDescriptor(DescriptorSet&& set) noexcept { _set = set; } inline void setDescriptor(DescriptorSet&& set) noexcept { _set = set; }
inline VkDescriptorSet getSet() noexcept { return _set.isInit() ? _set.get() : VK_NULL_HANDLE; } inline VkDescriptorSet getSet() noexcept { return _set.isInit() ? _set.get() : VK_NULL_HANDLE; }
inline void updateSet(int binding) const noexcept { _set.writeDescriptor(binding, getImageView(), getSampler()); } inline void updateSet(int binding) const noexcept { _set.writeDescriptor(binding, *this); }
~TextureAtlas() = default; ~TextureAtlas() = default;

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/01/25 11:59:07 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(); CmdBuffer& cmd = Render_Core::get().getSingleTimeCmdBuffer();
cmd.beginRecord(); cmd.beginRecord();
VkImageMemoryBarrier copy_barrier{}; VkImageLayout layout_save = _layout;
copy_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; transitionLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &cmd);
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, &copy_barrier);
VkBufferImageCopy region{}; VkBufferImageCopy region{};
region.bufferOffset = 0; region.bufferOffset = 0;
@@ -236,19 +226,7 @@ namespace mlx
vkCmdCopyBufferToImage(cmd.get(), buffer.get(), _image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region); vkCmdCopyBufferToImage(cmd.get(), buffer.get(), _image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
VkImageMemoryBarrier use_barrier{}; transitionLayout(layout_save, &cmd);
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);
cmd.endRecord(); cmd.endRecord();
cmd.submitIdle(); cmd.submitIdle();
@@ -259,18 +237,8 @@ namespace mlx
CmdBuffer& cmd = Render_Core::get().getSingleTimeCmdBuffer(); CmdBuffer& cmd = Render_Core::get().getSingleTimeCmdBuffer();
cmd.beginRecord(); cmd.beginRecord();
VkImageMemoryBarrier copy_barrier{}; VkImageLayout layout_save = _layout;
copy_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; transitionLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, &cmd);
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, &copy_barrier);
VkBufferImageCopy region{}; VkBufferImageCopy region{};
region.bufferOffset = 0; region.bufferOffset = 0;
@@ -285,31 +253,23 @@ namespace mlx
vkCmdCopyImageToBuffer(cmd.get(), _image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer.get(), 1, &region); vkCmdCopyImageToBuffer(cmd.get(), _image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, buffer.get(), 1, &region);
VkImageMemoryBarrier use_barrier{}; transitionLayout(layout_save, &cmd);
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);
cmd.endRecord(); cmd.endRecord();
cmd.submitIdle(); cmd.submitIdle();
} }
void Image::transitionLayout(VkImageLayout new_layout) void Image::transitionLayout(VkImageLayout new_layout, CmdBuffer* cmd)
{ {
if(new_layout == _layout) if(new_layout == _layout)
return; return;
CmdBuffer& cmd = Render_Core::get().getSingleTimeCmdBuffer(); bool singleTime = (cmd == nullptr);
cmd.beginRecord(); if(singleTime)
{
cmd = &Render_Core::get().getSingleTimeCmdBuffer();
cmd->beginRecord();
}
VkImageMemoryBarrier barrier{}; VkImageMemoryBarrier barrier{};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
@@ -344,10 +304,13 @@ namespace mlx
else else
destinationStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; 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(); if(singleTime)
cmd.submitIdle(); {
cmd->endRecord();
cmd->submitIdle();
}
_layout = new_layout; _layout = new_layout;
} }

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/01/25 11:54:21 by maldavid #+# #+# */ /* Created: 2023/01/25 11:54:21 by maldavid #+# #+# */
/* Updated: 2023/12/15 21:44:30 by maldavid ### ########.fr */ /* Updated: 2023/12/22 23:31:02 by kbz_8 ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -45,7 +45,7 @@ namespace mlx
void createSampler() noexcept; void createSampler() noexcept;
void copyFromBuffer(class Buffer& buffer); void copyFromBuffer(class Buffer& buffer);
void copyToBuffer(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; virtual void destroy() noexcept;
inline VkImage get() noexcept { return _image; } inline VkImage get() noexcept { return _image; }
@@ -53,6 +53,7 @@ namespace mlx
inline VkImageView getImageView() const noexcept { return _image_view; } inline VkImageView getImageView() const noexcept { return _image_view; }
inline VkFormat getFormat() const noexcept { return _format; } inline VkFormat getFormat() const noexcept { return _format; }
inline VkImageTiling getTiling() const noexcept { return _tiling; } inline VkImageTiling getTiling() const noexcept { return _tiling; }
inline VkImageLayout getLayout() const noexcept { return _layout; }
inline VkSampler getSampler() const noexcept { return _sampler; } inline VkSampler getSampler() const noexcept { return _sampler; }
inline uint32_t getWidth() const noexcept { return _width; } inline uint32_t getWidth() const noexcept { return _width; }
inline uint32_t getHeight() const noexcept { return _height; } inline uint32_t getHeight() const noexcept { return _height; }

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2022/12/18 21:27:38 by maldavid #+# #+# */ /* Created: 2022/12/18 21:27:38 by maldavid #+# #+# */
/* Updated: 2023/11/25 10:23:20 by maldavid ### ########.fr */ /* Updated: 2023/12/22 22:00:37 by kbz_8 ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -222,14 +222,14 @@ namespace mlx
VkViewport viewport{}; VkViewport viewport{};
viewport.x = 0.0f; viewport.x = 0.0f;
viewport.y = 0.0f; viewport.y = 0.0f;
viewport.width = (float)renderer.getSwapChain().getExtent().width; viewport.width = (float)renderer.getFrameBuffer(0).getWidth();
viewport.height = (float)renderer.getSwapChain().getExtent().height; viewport.height = (float)renderer.getFrameBuffer(0).getHeight();
viewport.minDepth = 0.0f; viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f; viewport.maxDepth = 1.0f;
VkRect2D scissor{}; VkRect2D scissor{};
scissor.offset = { 0, 0 }; scissor.offset = { 0, 0 };
scissor.extent = renderer.getSwapChain().getExtent(); scissor.extent = { renderer.getFrameBuffer(0).getWidth(), renderer.getFrameBuffer(0).getHeight()};
VkPipelineViewportStateCreateInfo viewportState{}; VkPipelineViewportStateCreateInfo viewportState{};
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/03/31 15:14:50 by maldavid #+# #+# */ /* Created: 2023/03/31 15:14:50 by maldavid #+# #+# */
/* Updated: 2023/12/14 18:26:03 by maldavid ### ########.fr */ /* Updated: 2023/12/23 19:34:30 by kbz_8 ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */

View File

@@ -6,25 +6,36 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2022/12/18 17:25:16 by maldavid #+# #+# */ /* Created: 2022/12/18 17:25:16 by maldavid #+# #+# */
/* Updated: 2023/12/10 22:21:10 by kbz_8 ### ########.fr */ /* Updated: 2023/12/24 16:04:04 by kbz_8 ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include <mutex> #include <mutex>
#include <renderer/renderer.h> #include <renderer/renderer.h>
#include <renderer/images/texture.h>
#include <renderer/core/render_core.h> #include <renderer/core/render_core.h>
namespace mlx namespace mlx
{ {
void Renderer::init() void Renderer::init(Texture* render_target)
{ {
_surface.create(*this); if(render_target == nullptr)
_swapchain.init(this); {
_pass.init(_swapchain.getImagesFormat()); _surface.create(*this);
_swapchain.init(this);
_pass.init(_swapchain.getImagesFormat(), VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
for(std::size_t i = 0; i < _swapchain.getImagesNumber(); i++)
_framebuffers.emplace_back().init(_pass, _swapchain.getImage(i));
}
else
{
_render_target = render_target;
_render_target->transitionLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
_pass.init(_render_target->getFormat(), _render_target->getLayout());
_framebuffers.emplace_back().init(_pass, *static_cast<Image*>(_render_target));
}
_cmd.init(); _cmd.init();
for(std::size_t i = 0; i < _swapchain.getImagesNumber(); i++)
_framebuffers.emplace_back().init(_pass, _swapchain.getImage(i));
for(std::size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) for(std::size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
_semaphores[i].init(); _semaphores[i].init();
@@ -62,19 +73,27 @@ namespace mlx
{ {
auto device = Render_Core::get().getDevice().get(); auto device = Render_Core::get().getDevice().get();
_cmd.getCmdBuffer(_current_frame_index).waitForExecution(); if(_render_target == nullptr)
_cmd.getCmdBuffer(_current_frame_index).reset();
VkResult result = vkAcquireNextImageKHR(device, _swapchain(), UINT64_MAX, _semaphores[_current_frame_index].getImageSemaphore(), VK_NULL_HANDLE, &_image_index);
if(result == VK_ERROR_OUT_OF_DATE_KHR)
{ {
_swapchain.recreate(); _cmd.getCmdBuffer(_current_frame_index).waitForExecution();
return false; VkResult result = vkAcquireNextImageKHR(device, _swapchain(), UINT64_MAX, _semaphores[_current_frame_index].getImageSemaphore(), VK_NULL_HANDLE, &_image_index);
}
else if(result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)
core::error::report(e_kind::fatal_error, "Vulkan error : failed to acquire swapchain image");
if(result == VK_ERROR_OUT_OF_DATE_KHR)
{
_swapchain.recreate();
return false;
}
else if(result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)
core::error::report(e_kind::fatal_error, "Vulkan error : failed to acquire swapchain image");
}
else
{
_image_index = 0;
if(_render_target->getLayout() != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
_render_target->transitionLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
}
_cmd.getCmdBuffer(_current_frame_index).reset();
_cmd.getCmdBuffer(_current_frame_index).beginRecord(); _cmd.getCmdBuffer(_current_frame_index).beginRecord();
auto& fb = _framebuffers[_image_index]; auto& fb = _framebuffers[_image_index];
_pass.begin(getActiveCmdBuffer(), fb); _pass.begin(getActiveCmdBuffer(), fb);
@@ -92,7 +111,7 @@ namespace mlx
VkRect2D scissor{}; VkRect2D scissor{};
scissor.offset = { 0, 0 }; scissor.offset = { 0, 0 };
scissor.extent = _swapchain.getExtent(); scissor.extent = { fb.getWidth(), fb.getHeight()};
vkCmdSetScissor(_cmd.getCmdBuffer(_current_frame_index).get(), 0, 1, &scissor); vkCmdSetScissor(_cmd.getCmdBuffer(_current_frame_index).get(), 0, 1, &scissor);
return true; return true;
@@ -102,30 +121,38 @@ namespace mlx
{ {
_pass.end(getActiveCmdBuffer()); _pass.end(getActiveCmdBuffer());
_cmd.getCmdBuffer(_current_frame_index).endRecord(); _cmd.getCmdBuffer(_current_frame_index).endRecord();
_cmd.getCmdBuffer(_current_frame_index).submit(_semaphores[_current_frame_index]);
VkSwapchainKHR swapchain = _swapchain(); if(_render_target == nullptr)
VkSemaphore signalSemaphores[] = { _semaphores[_current_frame_index].getRenderImageSemaphore() };
VkPresentInfoKHR presentInfo{};
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.waitSemaphoreCount = 1;
presentInfo.pWaitSemaphores = signalSemaphores;
presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = &swapchain;
presentInfo.pImageIndices = &_image_index;
VkResult result = vkQueuePresentKHR(Render_Core::get().getQueue().getPresent(), &presentInfo);
if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || _framebufferResized)
{ {
_framebufferResized = false; _cmd.getCmdBuffer(_current_frame_index).submit(&_semaphores[_current_frame_index]);
_swapchain.recreate();
}
else if(result != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan error : failed to present swap chain image");
_current_frame_index = (_current_frame_index + 1) % MAX_FRAMES_IN_FLIGHT; VkSwapchainKHR swapchain = _swapchain();
VkSemaphore signalSemaphores[] = { _semaphores[_current_frame_index].getRenderImageSemaphore() };
VkPresentInfoKHR presentInfo{};
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.waitSemaphoreCount = 1;
presentInfo.pWaitSemaphores = signalSemaphores;
presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = &swapchain;
presentInfo.pImageIndices = &_image_index;
VkResult result = vkQueuePresentKHR(Render_Core::get().getQueue().getPresent(), &presentInfo);
if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || _framebufferResized)
{
_framebufferResized = false;
_swapchain.recreate();
}
else if(result != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan error : failed to present swap chain image");
_current_frame_index = (_current_frame_index + 1) % MAX_FRAMES_IN_FLIGHT;
}
else
{
_cmd.getCmdBuffer(_current_frame_index).submitIdle();
_current_frame_index = 0;
}
} }
void Renderer::destroy() void Renderer::destroy()
@@ -139,11 +166,14 @@ namespace mlx
_cmd.destroy(); _cmd.destroy();
_desc_pool.destroy(); _desc_pool.destroy();
_pass.destroy(); _pass.destroy();
_swapchain.destroy(); if(_render_target == nullptr)
{
_swapchain.destroy();
_surface.destroy();
}
for(auto& fb : _framebuffers) for(auto& fb : _framebuffers)
fb.destroy(); fb.destroy();
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
_semaphores[i].destroy(); _semaphores[i].destroy();
_surface.destroy();
} }
} }

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2022/12/18 17:14:45 by maldavid #+# #+# */ /* Created: 2022/12/18 17:14:45 by maldavid #+# #+# */
/* Updated: 2023/12/10 22:19:41 by kbz_8 ### ########.fr */ /* Updated: 2023/12/22 21:59:15 by kbz_8 ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -83,7 +83,7 @@ namespace mlx
public: public:
Renderer() = default; Renderer() = default;
void init(); void init(class Texture* render_target);
bool beginFrame(); bool beginFrame();
void endFrame(); void endFrame();
@@ -102,6 +102,7 @@ namespace mlx
inline GraphicPipeline& getPipeline() noexcept { return _pipeline; } inline GraphicPipeline& getPipeline() noexcept { return _pipeline; }
inline CmdBuffer& getCmdBuffer(int i) noexcept { return _cmd.getCmdBuffer(i); } inline CmdBuffer& getCmdBuffer(int i) noexcept { return _cmd.getCmdBuffer(i); }
inline CmdBuffer& getActiveCmdBuffer() noexcept { return _cmd.getCmdBuffer(_current_frame_index); } inline CmdBuffer& getActiveCmdBuffer() noexcept { return _cmd.getCmdBuffer(_current_frame_index); }
inline FrameBuffer& getFrameBuffer(int i) noexcept { return _framebuffers[i]; }
inline DescriptorSet& getVertDescriptorSet() noexcept { return _vert_set; } inline DescriptorSet& getVertDescriptorSet() noexcept { return _vert_set; }
inline DescriptorSet& getFragDescriptorSet() noexcept { return _frag_set; } inline DescriptorSet& getFragDescriptorSet() noexcept { return _frag_set; }
inline DescriptorSetLayout& getVertDescriptorSetLayout() noexcept { return _vert_layout; } inline DescriptorSetLayout& getVertDescriptorSetLayout() noexcept { return _vert_layout; }
@@ -133,6 +134,7 @@ namespace mlx
std::unique_ptr<UBO> _uniform_buffer; std::unique_ptr<UBO> _uniform_buffer;
class MLX_Window* _window = nullptr; class MLX_Window* _window = nullptr;
class Texture* _render_target = nullptr;
uint32_t _current_frame_index = 0; uint32_t _current_frame_index = 0;
uint32_t _image_index = 0; uint32_t _image_index = 0;

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:21:36 by maldavid #+# #+# */ /* Created: 2022/10/06 18:21:36 by maldavid #+# #+# */
/* Updated: 2023/12/10 22:32:27 by kbz_8 ### ########.fr */ /* Updated: 2023/12/24 15:31:02 by kbz_8 ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -14,13 +14,12 @@
#include <renderer/core/render_core.h> #include <renderer/core/render_core.h>
#include <renderer/renderer.h> #include <renderer/renderer.h>
#include <renderer/renderpass/vk_framebuffer.h> #include <renderer/renderpass/vk_framebuffer.h>
#include <vulkan/vulkan_core.h>
namespace mlx namespace mlx
{ {
static const VkClearValue clearColor = {{{ 0.0f, 0.0f, 0.0f, 1.0f }}}; // wtf, this mess to satisfy a warning static const VkClearValue clearColor = {{{ 0.0f, 0.0f, 0.0f, 1.0f }}}; // wtf, this mess to satisfy a warning
void RenderPass::init(VkFormat attachement_format) void RenderPass::init(VkFormat attachement_format, VkImageLayout layout)
{ {
VkAttachmentDescription colorAttachment{}; VkAttachmentDescription colorAttachment{};
colorAttachment.format = attachement_format; colorAttachment.format = attachement_format;
@@ -30,23 +29,46 @@ namespace mlx
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; colorAttachment.finalLayout = layout;
VkAttachmentReference colorAttachmentRef{}; VkAttachmentReference colorAttachmentRef{};
colorAttachmentRef.attachment = 0; colorAttachmentRef.attachment = 0;
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; colorAttachmentRef.layout = (layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : layout);
VkSubpassDescription subpass{}; VkSubpassDescription subpass1{};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; subpass1.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.colorAttachmentCount = 1; subpass1.colorAttachmentCount = 1;
subpass.pColorAttachments = &colorAttachmentRef; subpass1.pColorAttachments = &colorAttachmentRef;
VkSubpassDescription subpasses[] = { subpass1 };
std::vector<VkSubpassDependency> subpassesDeps;
subpassesDeps.emplace_back();
subpassesDeps.back().srcSubpass = VK_SUBPASS_EXTERNAL;
subpassesDeps.back().dstSubpass = 0;
subpassesDeps.back().srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
subpassesDeps.back().dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
subpassesDeps.back().srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
subpassesDeps.back().dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
subpassesDeps.back().dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
subpassesDeps.emplace_back();
subpassesDeps.back().srcSubpass = 0;
subpassesDeps.back().dstSubpass = VK_SUBPASS_EXTERNAL;
subpassesDeps.back().srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
subpassesDeps.back().dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
subpassesDeps.back().srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
subpassesDeps.back().dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
subpassesDeps.back().dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
VkRenderPassCreateInfo renderPassInfo{}; VkRenderPassCreateInfo renderPassInfo{};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassInfo.attachmentCount = 1; renderPassInfo.attachmentCount = 1;
renderPassInfo.pAttachments = &colorAttachment; renderPassInfo.pAttachments = &colorAttachment;
renderPassInfo.subpassCount = 1; renderPassInfo.subpassCount = sizeof(subpasses) / sizeof(VkSubpassDescription);
renderPassInfo.pSubpasses = &subpass; renderPassInfo.pSubpasses = subpasses;
renderPassInfo.dependencyCount = static_cast<uint32_t>(subpassesDeps.size());
renderPassInfo.pDependencies = subpassesDeps.data();
if(vkCreateRenderPass(Render_Core::get().getDevice().get(), &renderPassInfo, nullptr, &_renderPass) != VK_SUCCESS) if(vkCreateRenderPass(Render_Core::get().getDevice().get(), &renderPassInfo, nullptr, &_renderPass) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create render pass"); core::error::report(e_kind::fatal_error, "Vulkan : failed to create render pass");
@@ -78,7 +100,6 @@ namespace mlx
{ {
if(!_is_running) if(!_is_running)
return; return;
vkCmdEndRenderPass(cmd.get()); vkCmdEndRenderPass(cmd.get());
_is_running = false; _is_running = false;
} }

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:22:00 by maldavid #+# #+# */ /* Created: 2022/10/06 18:22:00 by maldavid #+# #+# */
/* Updated: 2023/12/08 19:11:14 by kbz_8 ### ########.fr */ /* Updated: 2023/12/24 13:01:56 by kbz_8 ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -21,7 +21,7 @@ namespace mlx
class RenderPass class RenderPass
{ {
public: public:
void init(VkFormat attachement_format); void init(VkFormat attachement_format, VkImageLayout layout);
void destroy() noexcept; void destroy() noexcept;
void begin(class CmdBuffer& cmd, class FrameBuffer& fb); void begin(class CmdBuffer& cmd, class FrameBuffer& fb);

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */ /* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/04 17:55:21 by maldavid #+# #+# */ /* Created: 2022/10/04 17:55:21 by maldavid #+# #+# */
/* Updated: 2023/12/16 19:14:56 by maldavid ### ########.fr */ /* Updated: 2023/12/24 16:02:35 by kbz_8 ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */