diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index e82f86c..4d44976 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -50,18 +50,6 @@ jobs: - name: Update xmake repository run: xmake repo --update - # Fetch xmake dephash - - name: Retrieve dependencies hash - id: dep_hash - run: echo "hash=$(xmake l utils.ci.packageskey)" >> $GITHUB_OUTPUT - - # Cache xmake dependencies - - name: Retrieve cached xmake dependencies - uses: actions/cache@v3 - with: - path: ${{ env.XMAKE_GLOBALDIR }}/.xmake/packages - key: Windows-${{ matrix.arch }}-${{ matrix.mode }}-${{ steps.dep_hash.outputs.hash }}-W${{ steps.cache_key.outputs.key }} - # Setup compilation mode and install project dependencies - name: Configure xmake and install dependencies run: xmake config --arch=${{ matrix.arch }} --mode=${{ matrix.mode }} --yes diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..4bbaa90 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,17 @@ +# How to contribute to the MacroLibX + +For any questions, suggestions or help [contact me](mailto:contact@kbz8.me) + +## **Found a bug?** + +* Avoid opening any new issues without having checked if your problem has already been reported. If there are no currently open issues that fit your problem's description, feel free to [add it](https://github.com/seekrs/MacroLibX/issues/new). + +* When writing an issue make sure to include a clear title and description as well as having filled out all the necessary information: System info, OS, OS-Version, ... + +* If possible add pictures of the issue. + +## Contributing + +Before thinking of adding a contribution, think. Is it necessary? Will this actually be a useful/required feature? Is your implementation good? +Provide clear and documented explanation as to what was changed. + diff --git a/Makefile b/Makefile index 7a97434..831a281 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ # By: maldavid +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2022/10/04 16:43:41 by maldavid #+# #+# # -# Updated: 2023/12/12 13:38:08 by kbz_8 ### ########.fr # +# Updated: 2023/12/31 01:09:30 by maldavid ### ########.fr # # # # **************************************************************************** # @@ -31,7 +31,7 @@ MODE = "release" CXX = clang++ -CXXFLAGS = -std=c++17 -O3 -fPIC -Wall -Wextra -Werror +CXXFLAGS = -std=c++17 -O3 -fPIC -Wall -Wextra -Werror -DSDL_MAIN_HANDLED INCLUDES = -I./includes -I./src -I./third_party LDLIBS = diff --git a/includes/mlx.h b/includes/mlx.h index e2f2570..14f4453 100644 --- a/includes/mlx.h +++ b/includes/mlx.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 16:56:35 by maldavid #+# #+# */ -/* Updated: 2023/12/20 00:57:15 by kiroussa ### ########.fr */ +/* Updated: 2023/12/27 17:19:50 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -31,6 +31,7 @@ typedef enum MLX_WINDOW_EVENT = 5 } mlx_event_type; + /** * @brief Initializes the MLX internal application * @@ -38,6 +39,7 @@ typedef enum */ MLX_API void* mlx_init(); + /** * @brief Creates a new window * @@ -50,6 +52,7 @@ MLX_API void* mlx_init(); */ MLX_API void* mlx_new_window(void* mlx, int w, int h, const char* title); + /** * @brief Gives a function to be executed at each loop turn * @@ -59,9 +62,9 @@ MLX_API void* mlx_new_window(void* mlx, int w, int h, const char* title); * * @return (int) Always return 0, made this to copy the behaviour of the original MLX */ - MLX_API int mlx_loop_hook(void* mlx, int (*f)(void*), void* param); + /** * @brief Starts the internal main loop * @@ -71,6 +74,7 @@ MLX_API int mlx_loop_hook(void* mlx, int (*f)(void*), void* param); */ MLX_API int mlx_loop(void* mlx); + /** * @brief Ends the internal main loop * @@ -80,6 +84,7 @@ MLX_API int mlx_loop(void* mlx); */ MLX_API int mlx_loop_end(void* mlx); + /** * @brief Shows mouse cursor * @@ -87,6 +92,7 @@ MLX_API int mlx_loop_end(void* mlx); */ MLX_API int mlx_mouse_show(); + /** * @brief Hides mouse cursor * @@ -94,6 +100,7 @@ MLX_API int mlx_mouse_show(); */ MLX_API int mlx_mouse_hide(); + /** * @brief Moves cursor to givent position * @@ -106,6 +113,7 @@ MLX_API int mlx_mouse_hide(); */ MLX_API int mlx_mouse_move(void* mlx, void* win, int x, int y); + /** * @brief Get cursor's position * @@ -160,6 +168,7 @@ MLX_API int mlx_pixel_put(void* mlx, void* win, int x, int y, int color); */ MLX_API void* mlx_new_image(void* mlx, int width, int height); + /** * @brief Get image pixel data * @@ -180,6 +189,7 @@ MLX_API void* mlx_new_image(void* mlx, int width, int height); */ MLX_API int mlx_get_image_pixel(void* mlx, void* img, int x, int y); + /** * @brief Set image pixel data * @@ -201,6 +211,7 @@ MLX_API int mlx_get_image_pixel(void* mlx, void* img, int x, int y); */ MLX_API void mlx_set_image_pixel(void* mlx, void* img, int x, int y, int color); + /** * @brief Put image to the given window * @@ -214,6 +225,7 @@ MLX_API void mlx_set_image_pixel(void* mlx, void* img, int x, int y, int color); */ MLX_API int mlx_put_image_to_window(void* mlx, void* win, void* img, int x, int y); + /** * @brief Destroys internal image * @@ -237,6 +249,7 @@ MLX_API int mlx_destroy_image(void* mlx, void* img); */ MLX_API void* mlx_png_file_to_image(void* mlx, char* filename, int* width, int* height); + /** * @brief Create a new image from a jpg file * @@ -249,6 +262,7 @@ MLX_API void* mlx_png_file_to_image(void* mlx, char* filename, int* width, int* */ MLX_API void* mlx_jpg_file_to_image(void* mlx, char* filename, int* width, int* height); + /** * @brief Create a new image from a bmp file * @@ -288,6 +302,7 @@ MLX_API int mlx_string_put(void* mlx, void* win, int x, int y, int color, char* */ MLX_API void mlx_set_font(void* mlx, void* win, char* filepath); + /** * @brief Loads a font to be used by `mlx_string_put` and scales it * diff --git a/src/core/application.cpp b/src/core/application.cpp index 0a30f7b..21bc253 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -6,11 +6,12 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 22:10:52 by maldavid #+# #+# */ -/* Updated: 2023/12/15 20:51:41 by maldavid ### ########.fr */ +/* Updated: 2023/12/27 21:30:10 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ #include "application.h" +#include #include #include #include @@ -20,8 +21,12 @@ namespace mlx::core { + static bool __drop_sdl_responsability = false; Application::Application() : _in(std::make_unique()) { + __drop_sdl_responsability = SDL_WasInit(SDL_INIT_VIDEO); + if(__drop_sdl_responsability) // is case the mlx is running in a sandbox like MacroUnitTester where SDL is already init + return; SDL_SetMemoryFunctions(MemManager::malloc, MemManager::calloc, MemManager::realloc, MemManager::free); if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_TIMER) != 0) error::report(e_kind::fatal_error, "SDL error : unable to init all subsystems : %s", SDL_GetError()); @@ -32,14 +37,12 @@ namespace mlx::core while(_in->is_running()) { _in->update(); - for(auto& gs : _graphics) - gs->beginRender(); if(_loop_hook) _loop_hook(_param); for(auto& gs : _graphics) - gs->endRender(); + gs->render(); } } @@ -61,13 +64,15 @@ namespace mlx::core void Application::destroyTexture(void* ptr) { - vkDeviceWaitIdle(Render_Core::get().getDevice().get()); // TODO : synchronize with another method than stopping all the GPU porcess + vkDeviceWaitIdle(Render_Core::get().getDevice().get()); // TODO : synchronize with another method than stopping all the GPU process Texture* texture = static_cast(ptr); texture->destroy(); } Application::~Application() { + if(__drop_sdl_responsability) + return; SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_EVENTS); SDL_Quit(); } diff --git a/src/core/application.h b/src/core/application.h index 272bda1..24c2368 100644 --- a/src/core/application.h +++ b/src/core/application.h @@ -6,7 +6,7 @@ /* 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* 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 destroyGraphicsSupport(void* win); diff --git a/src/core/application.inl b/src/core/application.inl index d9c367a..3ecf15c 100644 --- a/src/core/application.inl +++ b/src/core/application.inl @@ -12,6 +12,18 @@ #include +#define CHECK_WINDOW_PTR(win) \ + if(win == nullptr) \ + { \ + core::error::report(e_kind::error, "invalid window ptr (NULL)"); \ + return; \ + } \ + else if(*static_cast(win) < 0 || *static_cast(win) > static_cast(_graphics.size()))\ + { \ + core::error::report(e_kind::error, "invalid window ptr"); \ + return; \ + } else {}\ + namespace mlx::core { void Application::getMousePos(int* x, int* y) noexcept @@ -22,6 +34,7 @@ namespace mlx::core void Application::mouseMove(void* win, int x, int y) noexcept { + CHECK_WINDOW_PTR(win); SDL_WarpMouseInWindow(_graphics[*static_cast(win)]->getWindow()->getNativeWindow(), x, y); SDL_PumpEvents(); SDL_FlushEvent(SDL_MOUSEMOTION); @@ -29,6 +42,7 @@ namespace mlx::core void Application::onEvent(void* win, int event, int (*funct_ptr)(int, void*), void* param) noexcept { + CHECK_WINDOW_PTR(win); _in->onEvent(_graphics[*static_cast(win)]->getWindow()->getID(), event, funct_ptr, param); } @@ -40,40 +54,55 @@ namespace mlx::core *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(w, h, title, _graphics.size())); - _in->addWindow(_graphics.back()->getWindow()); + auto it = std::find_if(_textures.begin(), _textures.end(), [=](const Texture& texture) + { + return &texture == reinterpret_cast(const_cast(title)); + }); + if(it != _textures.end()) + _graphics.emplace_back(std::make_unique(w, h, reinterpret_cast(const_cast(title)), _graphics.size())); + else + { + _graphics.emplace_back(std::make_unique(w, h, title, _graphics.size())); + _in->addWindow(_graphics.back()->getWindow()); + } return static_cast(&_graphics.back()->getID()); } void Application::clearGraphicsSupport(void* win) { + CHECK_WINDOW_PTR(win); _graphics[*static_cast(win)]->clearRenderData(); } void Application::destroyGraphicsSupport(void* win) { + CHECK_WINDOW_PTR(win); _graphics[*static_cast(win)].reset(); } void Application::pixelPut(void* win, int x, int y, uint32_t color) const noexcept { + CHECK_WINDOW_PTR(win); _graphics[*static_cast(win)]->pixelPut(x, y, color); } void Application::stringPut(void* win, int x, int y, int color, char* str) { + CHECK_WINDOW_PTR(win); _graphics[*static_cast(win)]->stringPut(x, y, color, str); } void Application::loadFont(void* win, const std::filesystem::path& filepath, float scale) { + CHECK_WINDOW_PTR(win); _graphics[*static_cast(win)]->loadFont(filepath, scale); } void Application::texturePut(void* win, void* img, int x, int y) { + CHECK_WINDOW_PTR(win); if(img == nullptr) { core::error::report(e_kind::error, "wrong texture (NULL)"); diff --git a/src/core/bridge.cpp b/src/core/bridge.cpp index 44d723f..beedec8 100644 --- a/src/core/bridge.cpp +++ b/src/core/bridge.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 17:35:20 by maldavid #+# #+# */ -/* Updated: 2023/12/16 20:20:41 by maldavid ### ########.fr */ +/* Updated: 2023/12/31 00:22:58 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -181,8 +181,8 @@ extern "C" unsigned char color_bits[4]; color_bits[0] = (color & 0x00FF0000) >> 16; color_bits[1] = (color & 0x0000FF00) >> 8; - color_bits[2] = color & 0x000000FF; - color_bits[3] = 0xFF; + color_bits[2] = (color & 0x000000FF); + color_bits[3] = (color & 0xFF000000) >> 24; static_cast(mlx)->pixelPut(win, x, y, *reinterpret_cast(color_bits)); return 0; } diff --git a/src/core/errors.h b/src/core/errors.h index d5aa359..9bfde94 100644 --- a/src/core/errors.h +++ b/src/core/errors.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 17:42:32 by maldavid #+# #+# */ -/* Updated: 2023/12/11 19:46:57 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/27 17:21:07 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/core/graphics.cpp b/src/core/graphics.cpp index bc4fd81..cd936f7 100644 --- a/src/core/graphics.cpp +++ b/src/core/graphics.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/04/02 15:13:55 by maldavid #+# #+# */ -/* Updated: 2023/12/15 21:04:50 by maldavid ### ########.fr */ +/* Updated: 2023/12/27 21:27:48 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,20 +14,40 @@ namespace mlx { - GraphicsSupport::GraphicsSupport(std::size_t w, std::size_t h, const std::string& title, int id) : - _window(std::make_shared(w, h, title)), + GraphicsSupport::GraphicsSupport(std::size_t w, std::size_t h, Texture* render_target, int id) : + _window(nullptr), _text_put_pipeline(std::make_unique()), - _renderer(std::make_unique()), + _renderer(std::make_unique()), + _width(w), + _height(h), _id(id) { - _renderer->setWindow(_window.get()); - _renderer->init(); + _renderer->setWindow(nullptr); + _renderer->init(render_target); _pixel_put_pipeline.init(w, h, *_renderer); _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(w, h, title)), + _text_put_pipeline(std::make_unique()), + _renderer(std::make_unique()), + _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(0, _width, 0, _height); + _renderer->getUniformBuffer()->setData(sizeof(_proj), &_proj); auto cmd_buff = _renderer->getActiveCmdBuffer().get(); static std::array sets = { @@ -41,6 +61,8 @@ namespace mlx continue; if(data.texture->getSet() == VK_NULL_HANDLE) 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()) data.texture->updateSet(0); sets[1] = data.texture->getSet(); @@ -76,6 +98,7 @@ namespace mlx _text_put_pipeline->destroy(); _pixel_put_pipeline.destroy(); _renderer->destroy(); - _window->destroy(); + if(_window) + _window->destroy(); } } diff --git a/src/core/graphics.h b/src/core/graphics.h index ffd8e56..04f66b0 100644 --- a/src/core/graphics.h +++ b/src/core/graphics.h @@ -6,7 +6,7 @@ /* 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 { 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 std::shared_ptr getWindow(); - inline void beginRender() noexcept; - void endRender() noexcept; + void render() noexcept; inline void clearRenderData() noexcept; inline void pixelPut(int x, int y, uint32_t color) noexcept; @@ -56,6 +56,8 @@ namespace mlx std::shared_ptr _window; std::unique_ptr _text_put_pipeline; // unique_ptr because of the size of the class std::unique_ptr _renderer; + std::size_t _width = 0; + std::size_t _height = 0; int _id; }; } diff --git a/src/core/graphics.inl b/src/core/graphics.inl index 54f00ee..a03bd9f 100644 --- a/src/core/graphics.inl +++ b/src/core/graphics.inl @@ -10,7 +10,6 @@ /* */ /* ************************************************************************** */ -#include "renderer/images/texture.h" #include #include @@ -19,14 +18,6 @@ namespace mlx int& GraphicsSupport::getID() noexcept { return _id; } std::shared_ptr GraphicsSupport::getWindow() { return _window; } - void GraphicsSupport::beginRender() noexcept - { - if(!_renderer->beginFrame()) - return; - _proj = glm::ortho(0, _window->getWidth(), 0, _window->getHeight()); - _renderer->getUniformBuffer()->setData(sizeof(_proj), &_proj); - } - void GraphicsSupport::clearRenderData() noexcept { _textures_to_render.clear(); diff --git a/src/platform/window.cpp b/src/platform/window.cpp index 39b6093..aee77aa 100644 --- a/src/platform/window.cpp +++ b/src/platform/window.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 17:36:44 by maldavid #+# #+# */ -/* Updated: 2023/12/10 22:49:11 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/27 16:57:28 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -31,6 +31,8 @@ namespace mlx MLX_Window::MLX_Window(std::size_t w, std::size_t h, const std::string& title) : _width(w), _height(h) { + if(title.find("vvaas") != std::string::npos) + core::error::report(e_kind::message, "vvaas est mauvais"); _win = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, w, h, SDL_WINDOW_VULKAN | SDL_WINDOW_SHOWN); if(!_win) core::error::report(e_kind::fatal_error, std::string("unable to open a new window, ") + SDL_GetError()); diff --git a/src/platform/window.h b/src/platform/window.h index b362b90..876c14b 100644 --- a/src/platform/window.h +++ b/src/platform/window.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 21:53:12 by maldavid #+# #+# */ -/* Updated: 2023/12/11 19:47:26 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/21 00:24:26 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/renderer/command/vk_cmd_buffer.cpp b/src/renderer/command/vk_cmd_buffer.cpp index e417508..b1dade7 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/24 12:58:36 by kbz_8 ### ########.fr */ /* */ /* ************************************************************************** */ @@ -85,28 +85,40 @@ namespace mlx VkFence fence; vkCreateFence(device, &fenceCreateInfo, nullptr, &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); 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(); + } + else + { + signalSemaphores[0] = nullptr; + waitSemaphores[0] = nullptr; + } 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/core/memory.cpp b/src/renderer/core/memory.cpp index 5ff7c67..8712085 100644 --- a/src/renderer/core/memory.cpp +++ b/src/renderer/core/memory.cpp @@ -6,7 +6,7 @@ /* By: kbz_8 +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/20 22:02:37 by kbz_8 #+# #+# */ -/* Updated: 2023/12/16 19:14:15 by maldavid ### ########.fr */ +/* Updated: 2023/12/27 21:31:04 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,11 +17,7 @@ #define VMA_STATIC_VULKAN_FUNCTIONS 0 #define VMA_DYNAMIC_VULKAN_FUNCTIONS 0 #define VMA_VULKAN_VERSION 1002000 -#ifdef DEBUG - #define VMA_ASSERT(expr) (static_cast(expr) ? void(0) : mlx::core::error::report(e_kind::fatal_error, "Graphics allocator : an assertion has been catched : '%s'", #expr)) -#else - #define VMA_ASSERT(expr) ((void)0) -#endif +#define VMA_ASSERT(expr) ((void)0) #define VMA_IMPLEMENTATION #ifdef MLX_COMPILER_CLANG @@ -177,5 +173,7 @@ namespace mlx 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), please report, this should not happen", _active_buffers_allocations); vmaDestroyAllocator(_allocator); + _active_buffers_allocations = 0; + _active_images_allocations = 0; } } diff --git a/src/renderer/core/render_core.h b/src/renderer/core/render_core.h index a318ff4..a4cd398 100644 --- a/src/renderer/core/render_core.h +++ b/src/renderer/core/render_core.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/08 19:16:32 by maldavid #+# #+# */ -/* Updated: 2023/12/15 20:31:08 by maldavid ### ########.fr */ +/* Updated: 2023/12/31 00:42:42 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/renderer/core/vk_device.cpp b/src/renderer/core/vk_device.cpp index 0322030..f10c599 100644 --- a/src/renderer/core/vk_device.cpp +++ b/src/renderer/core/vk_device.cpp @@ -6,11 +6,12 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/08 19:14:29 by maldavid #+# #+# */ -/* Updated: 2023/12/12 15:50:02 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/30 23:29:41 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ #include "render_core.h" +#include #include #include #include @@ -85,8 +86,10 @@ namespace mlx std::vector> devices_score; - for(const auto& device : devices) - devices_score.emplace_back(deviceScore(device, surface), device); + std::transform(devices.cbegin(), devices.cend(), std::back_inserter(devices_score), [&](VkPhysicalDevice device) + { + return std::make_pair(deviceScore(device, surface), device); + }); vkDestroySurfaceKHR(Render_Core::get().getInstance().get(), surface, nullptr); SDL_DestroyWindow(window); diff --git a/src/renderer/core/vk_instance.cpp b/src/renderer/core/vk_instance.cpp index 3a51c75..d93f342 100644 --- a/src/renderer/core/vk_instance.cpp +++ b/src/renderer/core/vk_instance.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/08 19:04:21 by maldavid #+# #+# */ -/* Updated: 2023/12/15 16:20:26 by maldavid ### ########.fr */ +/* Updated: 2023/12/31 00:40:10 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,13 +25,15 @@ namespace mlx appInfo.engineVersion = VK_MAKE_VERSION(1, 2, 1); appInfo.apiVersion = VK_API_VERSION_1_2; + auto extensions = getRequiredExtensions(); + VkInstanceCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.pApplicationInfo = &appInfo; - - auto extensions = getRequiredExtensions(); createInfo.enabledExtensionCount = static_cast(extensions.size()); createInfo.ppEnabledExtensionNames = extensions.data(); + createInfo.enabledLayerCount = 0; // will be replaced if validation layers are enabled + createInfo.pNext = nullptr; VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo; if constexpr(enableValidationLayers) @@ -41,14 +43,9 @@ namespace mlx createInfo.enabledLayerCount = static_cast(validationLayers.size()); createInfo.ppEnabledLayerNames = validationLayers.data(); Render_Core::get().getLayers().populateDebugMessengerCreateInfo(debugCreateInfo); - createInfo.pNext = (VkDebugUtilsMessengerCreateInfoEXT*) &debugCreateInfo; + createInfo.pNext = static_cast(&debugCreateInfo); } } - else - { - createInfo.enabledLayerCount = 0; - createInfo.pNext = nullptr; - } VkResult res; if((res = vkCreateInstance(&createInfo, nullptr, &_instance)) != VK_SUCCESS) diff --git a/src/renderer/core/vk_surface.cpp b/src/renderer/core/vk_surface.cpp index fdc027c..3a5fed2 100644 --- a/src/renderer/core/vk_surface.cpp +++ b/src/renderer/core/vk_surface.cpp @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/08 18:58:49 by maldavid #+# #+# */ -/* Updated: 2023/11/18 17:22:38 by maldavid ### ########.fr */ +/* Updated: 2023/12/30 23:14:54 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,6 +15,7 @@ #include #include #include +#include namespace mlx { @@ -29,13 +30,12 @@ namespace mlx VkSurfaceFormatKHR Surface::chooseSwapSurfaceFormat(const std::vector& availableFormats) { - for(const auto& availableFormat : availableFormats) + auto it = std::find_if(availableFormats.begin(), availableFormats.end(), [](VkSurfaceFormatKHR format) { - if(availableFormat.format == VK_FORMAT_R8G8B8A8_SRGB && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) - return availableFormat; - } + return format.format == VK_FORMAT_R8G8B8A8_SRGB && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; + }); - return availableFormats[0]; + return (it == availableFormats.end() ? availableFormats[0] : *it); } void Surface::destroy() noexcept diff --git a/src/renderer/core/vk_validation_layers.cpp b/src/renderer/core/vk_validation_layers.cpp index 27d7341..837aa1b 100644 --- a/src/renderer/core/vk_validation_layers.cpp +++ b/src/renderer/core/vk_validation_layers.cpp @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* vk_validation_layers.cpp :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: maldavid +#+ +:+ +#+ */ +/* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/12/19 14:05:25 by maldavid #+# #+# */ -/* Updated: 2023/12/10 22:25:36 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/31 00:41:39 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,6 +16,7 @@ #include #include #include +#include namespace mlx { @@ -24,10 +25,10 @@ namespace mlx if constexpr(!enableValidationLayers) return; - VkDebugUtilsMessengerCreateInfoEXT createInfo; + VkDebugUtilsMessengerCreateInfoEXT createInfo{}; populateDebugMessengerCreateInfo(createInfo); if(createDebugUtilsMessengerEXT(&createInfo, nullptr) != VK_SUCCESS) - core::error::report(e_kind::error, "Vulkan : failed to set up debug messenger"); + core::error::report(e_kind::warning, "Vulkan : failed to set up debug messenger"); #ifdef DEBUG else core::error::report(e_kind::message, "Vulkan : enabled validation layers"); @@ -42,36 +43,15 @@ namespace mlx std::vector availableLayers(layerCount); vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data()); - for(const char* layerName : validationLayers) + return std::all_of(validationLayers.begin(), validationLayers.end(), [&](const char* layerName) { - bool layerFound = false; - - for(const auto& layerProperties : availableLayers) + if(!std::any_of(availableLayers.begin(), availableLayers.end(), [=](VkLayerProperties props) { return std::strcmp(layerName, props.layerName) == 0; })) { - if(std::strcmp(layerName, layerProperties.layerName) == 0) - { - layerFound = true; - break; - } - } - - if(!layerFound) + core::error::report(e_kind::error, "Vulkan : a validation layer was requested but was not found ('%s')", layerName); return false; - } - return true; - } - - void ValidationLayers::destroy() - { - if constexpr(!enableValidationLayers) - return; - destroyDebugUtilsMessengerEXT(nullptr); - } - - 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, &_debugMessenger) : VK_ERROR_EXTENSION_NOT_PRESENT; + } + return true; + }); } void ValidationLayers::populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& createInfo) @@ -83,6 +63,19 @@ namespace mlx createInfo.pfnUserCallback = ValidationLayers::debugCallback; } + + void ValidationLayers::destroy() + { + if constexpr(enableValidationLayers) + destroyDebugUtilsMessengerEXT(nullptr); + } + + 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, &_debugMessenger) : 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) { if(messageSeverity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) diff --git a/src/renderer/core/vk_validation_layers.h b/src/renderer/core/vk_validation_layers.h index 41a0909..1d3a586 100644 --- a/src/renderer/core/vk_validation_layers.h +++ b/src/renderer/core/vk_validation_layers.h @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/12/19 14:04:25 by maldavid #+# #+# */ -/* Updated: 2023/12/08 19:09:02 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/31 00:38:25 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,16 +21,19 @@ namespace mlx class ValidationLayers { public: + ValidationLayers() = default; void init(); - void destroy(); bool checkValidationLayerSupport(); void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT& createInfo); + void destroy(); + ~ValidationLayers() = default; private: VkResult createDebugUtilsMessengerEXT(const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator); static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData); void destroyDebugUtilsMessengerEXT(const VkAllocationCallbacks* pAllocator); + private: VkDebugUtilsMessengerEXT _debugMessenger; }; } diff --git a/src/renderer/descriptors/vk_descriptor_set.cpp b/src/renderer/descriptors/vk_descriptor_set.cpp index f0365a1..cf6a624 100644 --- a/src/renderer/descriptors/vk_descriptor_set.cpp +++ b/src/renderer/descriptors/vk_descriptor_set.cpp @@ -6,7 +6,7 @@ /* 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 #include +#include 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(); VkDescriptorImageInfo imageInfo{}; - imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - imageInfo.imageView = view; - imageInfo.sampler = sampler; + imageInfo.imageLayout = image.getLayout(); + imageInfo.imageView = image.getImageView(); + imageInfo.sampler = image.getSampler(); VkWriteDescriptorSet descriptorWrite{}; descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; diff --git a/src/renderer/descriptors/vk_descriptor_set.h b/src/renderer/descriptors/vk_descriptor_set.h index 601032f..f1e627d 100644 --- a/src/renderer/descriptors/vk_descriptor_set.h +++ b/src/renderer/descriptors/vk_descriptor_set.h @@ -6,7 +6,7 @@ /* 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 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; } diff --git a/src/renderer/images/texture.cpp b/src/renderer/images/texture.cpp index 3d43381..5a3b3da 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/10 22:46:08 by kbz_8 ### ########.fr */ +/* Updated: 2023/12/31 00:49:16 by maldavid ### ########.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) { - 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::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}}, @@ -53,18 +54,27 @@ namespace mlx _ibo.create(sizeof(uint16_t) * indexData.size(), indexData.data(), nullptr); #endif + Buffer staging_buffer; + std::size_t size = width * height * formatSize(format); if(pixels != nullptr) { - Buffer staging_buffer; - std::size_t size = width * height * formatSize(format); #ifdef DEBUG staging_buffer.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, name, pixels); #else staging_buffer.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, nullptr, pixels); #endif - Image::copyFromBuffer(staging_buffer); - staging_buffer.destroy(); } + else + { + std::vector default_pixels(width * height, 0x00000000); + #ifdef DEBUG + staging_buffer.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, name, default_pixels.data()); + #else + staging_buffer.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, nullptr, default_pixels.data()); + #endif + } + Image::copyFromBuffer(staging_buffer); + staging_buffer.destroy(); } void Texture::setPixel(int x, int y, uint32_t color) noexcept @@ -119,12 +129,12 @@ namespace mlx Image::copyFromBuffer(*_buf_map); _has_been_modified = false; } - auto cmd = renderer.getActiveCmdBuffer().get(); + auto cmd = renderer.getActiveCmdBuffer(); _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); } void Texture::destroy() noexcept @@ -147,11 +157,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.h b/src/renderer/images/texture.h index 725b37a..19f7d24 100644 --- a/src/renderer/images/texture.h +++ b/src/renderer/images/texture.h @@ -6,7 +6,7 @@ /* 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 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 constexpr void resetUpdate() noexcept { _has_been_updated = false; } diff --git a/src/renderer/images/texture_atlas.cpp b/src/renderer/images/texture_atlas.cpp index be611bc..b6eb61b 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/31 00:52:01 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,15 +25,18 @@ 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) + if(pixels == nullptr) { - Buffer staging_buffer; - std::size_t size = width * height * formatSize(format); - staging_buffer.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, name, pixels); - Image::copyFromBuffer(staging_buffer); - staging_buffer.destroy(); + core::error::report(e_kind::warning, "Renderer : creating an empty texture atlas. They cannot be updated after creation, this might be a mistake or a bug, please report"); + return; } + Buffer staging_buffer; + std::size_t size = width * height * formatSize(format); + staging_buffer.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, name, pixels); + Image::copyFromBuffer(staging_buffer); + staging_buffer.destroy(); } void TextureAtlas::render(Renderer& renderer, int x, int y, uint32_t ibo_size) const diff --git a/src/renderer/images/texture_atlas.h b/src/renderer/images/texture_atlas.h index 1cb8c09..6191ca9 100644 --- a/src/renderer/images/texture_atlas.h +++ b/src/renderer/images/texture_atlas.h @@ -6,7 +6,7 @@ /* 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 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; 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 a5600e6..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/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 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; } @@ -53,6 +53,7 @@ namespace mlx inline VkImageView getImageView() const noexcept { return _image_view; } inline VkFormat getFormat() const noexcept { return _format; } inline VkImageTiling getTiling() const noexcept { return _tiling; } + inline VkImageLayout getLayout() const noexcept { return _layout; } inline VkSampler getSampler() const noexcept { return _sampler; } inline uint32_t getWidth() const noexcept { return _width; } inline uint32_t getHeight() const noexcept { return _height; } diff --git a/src/renderer/pipeline/pipeline.cpp b/src/renderer/pipeline/pipeline.cpp index cc02741..9d962bb 100644 --- a/src/renderer/pipeline/pipeline.cpp +++ b/src/renderer/pipeline/pipeline.cpp @@ -6,7 +6,7 @@ /* 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{}; viewport.x = 0.0f; viewport.y = 0.0f; - viewport.width = (float)renderer.getSwapChain().getExtent().width; - viewport.height = (float)renderer.getSwapChain().getExtent().height; + viewport.width = (float)renderer.getFrameBuffer(0).getWidth(); + viewport.height = (float)renderer.getFrameBuffer(0).getHeight(); viewport.minDepth = 0.0f; viewport.maxDepth = 1.0f; VkRect2D scissor{}; scissor.offset = { 0, 0 }; - scissor.extent = renderer.getSwapChain().getExtent(); + scissor.extent = { renderer.getFrameBuffer(0).getWidth(), renderer.getFrameBuffer(0).getHeight()}; VkPipelineViewportStateCreateInfo viewportState{}; viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; diff --git a/src/renderer/pixel_put.cpp b/src/renderer/pixel_put.cpp index 7dcff20..c94d30b 100644 --- a/src/renderer/pixel_put.cpp +++ b/src/renderer/pixel_put.cpp @@ -6,7 +6,7 @@ /* 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 */ /* */ /* ************************************************************************** */ @@ -56,7 +56,7 @@ namespace mlx { _texture.render(renderer, 0, 0); } - + void PixelPutPipeline::destroy() noexcept { _buffer.destroy(); diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 27667ec..2a57b20 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -6,28 +6,39 @@ /* 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 #include +#include #include namespace mlx { - void Renderer::init() + void Renderer::init(Texture* render_target) { - _surface.create(*this); - _swapchain.init(this); - _pass.init(_swapchain.getImagesFormat()); + if(render_target == nullptr) + { + _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(_render_target)); + } _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++) _semaphores[i].init(); - + _uniform_buffer.reset(new UBO); #ifdef DEBUG _uniform_buffer->create(this, sizeof(glm::mat4), "__mlx_matrices_uniform_buffer_"); @@ -40,14 +51,14 @@ namespace mlx { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 4096 } }; _desc_pool.init(2, pool_sizes); - + _vert_layout.init({ {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER} }, VK_SHADER_STAGE_VERTEX_BIT); _frag_layout.init({ {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER} }, VK_SHADER_STAGE_FRAGMENT_BIT); - + _vert_set.init(this, &_desc_pool, &_vert_layout); _frag_set.init(this, &_desc_pool, &_frag_layout); @@ -62,19 +73,27 @@ namespace mlx { auto device = Render_Core::get().getDevice().get(); - _cmd.getCmdBuffer(_current_frame_index).waitForExecution(); - _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) + if(_render_target == nullptr) { - _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"); + _cmd.getCmdBuffer(_current_frame_index).waitForExecution(); + 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(); + 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(); auto& fb = _framebuffers[_image_index]; _pass.begin(getActiveCmdBuffer(), fb); @@ -92,7 +111,7 @@ namespace mlx VkRect2D scissor{}; scissor.offset = { 0, 0 }; - scissor.extent = _swapchain.getExtent(); + scissor.extent = { fb.getWidth(), fb.getHeight()}; vkCmdSetScissor(_cmd.getCmdBuffer(_current_frame_index).get(), 0, 1, &scissor); return true; @@ -102,30 +121,38 @@ namespace mlx { _pass.end(getActiveCmdBuffer()); _cmd.getCmdBuffer(_current_frame_index).endRecord(); - _cmd.getCmdBuffer(_current_frame_index).submit(_semaphores[_current_frame_index]); - 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) + if(_render_target == nullptr) { - _framebufferResized = false; - _swapchain.recreate(); - } - else if(result != VK_SUCCESS) - core::error::report(e_kind::fatal_error, "Vulkan error : failed to present swap chain image"); + _cmd.getCmdBuffer(_current_frame_index).submit(&_semaphores[_current_frame_index]); - _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() @@ -139,11 +166,14 @@ namespace mlx _cmd.destroy(); _desc_pool.destroy(); _pass.destroy(); - _swapchain.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(); - _surface.destroy(); } } diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 1dedc61..fcd820c 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -6,7 +6,7 @@ /* 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: Renderer() = default; - void init(); + void init(class Texture* render_target); bool beginFrame(); void endFrame(); @@ -102,6 +102,7 @@ namespace mlx inline GraphicPipeline& getPipeline() noexcept { return _pipeline; } inline CmdBuffer& getCmdBuffer(int i) noexcept { return _cmd.getCmdBuffer(i); } 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& getFragDescriptorSet() noexcept { return _frag_set; } inline DescriptorSetLayout& getVertDescriptorSetLayout() noexcept { return _vert_layout; } @@ -133,6 +134,7 @@ namespace mlx std::unique_ptr _uniform_buffer; class MLX_Window* _window = nullptr; + class Texture* _render_target = nullptr; uint32_t _current_frame_index = 0; uint32_t _image_index = 0; diff --git a/src/renderer/renderpass/vk_render_pass.cpp b/src/renderer/renderpass/vk_render_pass.cpp index 710681f..2c2dc9c 100644 --- a/src/renderer/renderpass/vk_render_pass.cpp +++ b/src/renderer/renderpass/vk_render_pass.cpp @@ -6,7 +6,7 @@ /* 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 #include #include -#include namespace mlx { 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{}; colorAttachment.format = attachement_format; @@ -30,23 +29,46 @@ namespace mlx colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + colorAttachment.finalLayout = layout; VkAttachmentReference colorAttachmentRef{}; 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{}; - subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpass.colorAttachmentCount = 1; - subpass.pColorAttachments = &colorAttachmentRef; + VkSubpassDescription subpass1{}; + subpass1.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + subpass1.colorAttachmentCount = 1; + subpass1.pColorAttachments = &colorAttachmentRef; + + VkSubpassDescription subpasses[] = { subpass1 }; + + std::vector 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{}; renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; renderPassInfo.attachmentCount = 1; renderPassInfo.pAttachments = &colorAttachment; - renderPassInfo.subpassCount = 1; - renderPassInfo.pSubpasses = &subpass; + renderPassInfo.subpassCount = sizeof(subpasses) / sizeof(VkSubpassDescription); + renderPassInfo.pSubpasses = subpasses; + renderPassInfo.dependencyCount = static_cast(subpassesDeps.size()); + renderPassInfo.pDependencies = subpassesDeps.data(); 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"); @@ -78,7 +100,6 @@ namespace mlx { if(!_is_running) return; - vkCmdEndRenderPass(cmd.get()); _is_running = false; } diff --git a/src/renderer/renderpass/vk_render_pass.h b/src/renderer/renderpass/vk_render_pass.h index bc2171b..3d57b4d 100644 --- a/src/renderer/renderpass/vk_render_pass.h +++ b/src/renderer/renderpass/vk_render_pass.h @@ -6,7 +6,7 @@ /* 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 { public: - void init(VkFormat attachement_format); + void init(VkFormat attachement_format, VkImageLayout layout); void destroy() noexcept; void begin(class CmdBuffer& cmd, class FrameBuffer& fb); diff --git a/test/main.c b/test/main.c index 851aeda..682d4de 100644 --- a/test/main.c +++ b/test/main.c @@ -6,7 +6,7 @@ /* By: maldavid +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2022/10/04 17:55:21 by maldavid #+# #+# */ -/* Updated: 2023/12/16 19:14:56 by maldavid ### ########.fr */ +/* Updated: 2023/12/31 01:13:40 by maldavid ### ########.fr */ /* */ /* ************************************************************************** */ @@ -93,13 +93,15 @@ int window_hook(int event, void *param) return (0); } -int main(void) +int main(int argc, char* argv[]) { t_mlx mlx; void *img; int w; int h; + (void)argc; + (void)argv; mlx.mlx = mlx_init(); mlx.win = mlx_new_window(mlx.mlx, 400, 400, "My window"); mlx_on_event(mlx.mlx, mlx.win, MLX_KEYDOWN, key_hook, &mlx); diff --git a/xmake.lua b/xmake.lua index 7048f27..885bf81 100644 --- a/xmake.lua +++ b/xmake.lua @@ -12,7 +12,8 @@ -- Global settings -add_requires("libsdl", "vulkan-headers") +add_requires("vulkan-headers") +add_requires("libsdl", {configs = { sdlmain = false }}) add_rules("mode.debug", "mode.release") set_languages("cxx17", "c99") @@ -50,7 +51,7 @@ target("mlx") add_options("graphics_memory_dump") add_includedirs("includes", "src", "third_party") - add_defines("MLX_BUILD") + add_defines("MLX_BUILD", "SDL_MAIN_HANDLED") add_files("src/**.cpp") @@ -72,5 +73,7 @@ target("Test") add_files("test/main.c") + add_defines("SDL_MAIN_HANDLED") + add_packages("libsdl") target_end()