almost first rendering, fixing renderer issues

This commit is contained in:
Kbz-8
2022-12-19 00:59:45 +01:00
parent 4a67aab716
commit f1e0499564
417 changed files with 60861 additions and 298 deletions

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/04 22:10:52 by maldavid #+# #+# */
/* Updated: 2022/12/18 02:49:45 by maldavid ### ########.fr */
/* Updated: 2022/12/19 00:40:17 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -19,8 +19,14 @@ namespace mlx::core
while(_in.is_running())
{
_in.update();
for(auto win : _wins)
win->beginFrame();
if(_loop_hook)
_loop_hook(_param);
for(auto win : _wins)
win->endFrame();
}
}
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/04 21:49:46 by maldavid #+# #+# */
/* Updated: 2022/12/18 03:45:13 by maldavid ### ########.fr */
/* Updated: 2022/12/18 23:10:17 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -28,7 +28,7 @@ namespace mlx::core
class Application
{
public:
Application() : _in(_wins) {}
Application() : _in() {}
inline void* new_window(std::size_t w, std::size_t h, std::string title)
{

View File

@@ -6,19 +6,20 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/04 17:35:20 by maldavid #+# #+# */
/* Updated: 2022/12/18 03:42:18 by maldavid ### ########.fr */
/* Updated: 2022/12/18 22:24:25 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <iostream>
#include <SDL2/SDL.h>
#include "errors.h"
#include "application.h"
#include <renderer/core/render_core.h>
extern "C"
{
void* mlx_init()
{
mlx::Render_Core::get().init();
return new mlx::core::Application();
}
@@ -78,6 +79,7 @@ extern "C"
int mlx_destroy_display(void* mlx)
{
delete static_cast<mlx::core::Application*>(mlx);
mlx::Render_Core::get().destroy();
return 0;
}
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/04 17:48:06 by maldavid #+# #+# */
/* Updated: 2022/12/17 23:28:22 by maldavid ### ########.fr */
/* Updated: 2022/12/18 17:47:51 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -21,21 +21,21 @@ namespace mlx::core::error
{
void report(e_kind kind, std::string msg, ...)
{
char buffer[1024];
char buffer[4096];
va_list al;
va_start(al, msg);
std::vsprintf(buffer, std::move(msg).c_str(), al);
std::vsprintf(buffer, msg.c_str(), al);
va_end(al);
switch(kind)
{
case e_kind::message: std::cout << "[MicroLibX] Message : " << buffer << std::endl; break;
case e_kind::warning: std::cout << "[MicroLibX] Warning : " << buffer << std::endl; break;
case e_kind::error: std::cerr << "[MicroLibX] Error : " << buffer << std::endl; break;
case e_kind::message: std::cout << "[MacroLibX] Message : " << buffer << std::endl; break;
case e_kind::warning: std::cout << "[MacroLibX] Warning : " << buffer << std::endl; break;
case e_kind::error: std::cerr << "[MacroLibX] Error : " << buffer << std::endl; break;
case e_kind::fatal_error:
std::cerr << "[MicroLibX] Fatal Error : " << buffer << std::endl;
std::exit(EXIT_SUCCESS);
std::cerr << "[MacroLibX] Fatal Error : " << buffer << std::endl;
std::exit(EXIT_FAILURE);
break;
}
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/05 16:30:19 by maldavid #+# #+# */
/* Updated: 2022/12/18 01:13:32 by maldavid ### ########.fr */
/* Updated: 2022/12/18 23:09:55 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -15,7 +15,7 @@
namespace mlx
{
Input::Input(const std::vector<std::shared_ptr<MLX_Window>>& wins) : _wins(wins)
Input::Input()
{
std::memset(_keys.data(), 0, SDL_NUM_SCANCODES);
std::memset(_mouse.data(), 0, 8);

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/05 16:27:35 by maldavid #+# #+# */
/* Updated: 2022/12/18 01:13:19 by maldavid ### ########.fr */
/* Updated: 2022/12/18 23:09:41 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -25,7 +25,7 @@ namespace mlx
class Input
{
public:
Input(const std::vector<std::shared_ptr<MLX_Window>>& wins);
Input();
void update();
@@ -49,7 +49,6 @@ namespace mlx
SDL_Event _event;
std::array<uint8_t, SDL_NUM_SCANCODES> _keys;
std::array<uint8_t, 8> _mouse;
std::vector<std::shared_ptr<MLX_Window>> _wins;
int _x = 0;
int _y = 0;

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/04 17:36:44 by maldavid #+# #+# */
/* Updated: 2022/12/18 01:12:05 by maldavid ### ########.fr */
/* Updated: 2022/12/19 00:46:55 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -15,15 +15,44 @@
namespace mlx
{
MLX_Window::MLX_Window(std::size_t w, std::size_t h, std::string title, int id) : _id(id)
MLX_Window::MLX_Window(std::size_t w, std::size_t h, std::string title, int id) : _id(id), _renderer(new Renderer())
{
_win = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, w, h, /*SDL_WINDOW_VULKAN |*/ SDL_WINDOW_SHOWN);
_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());
_renderer->setWindow(this);
_renderer->init();
_vbo.create(sizeof(Vertex));
}
bool MLX_Window::beginFrame()
{
return _renderer->beginFrame();
}
void MLX_Window::pixel_put(int x, int y, int color)
{
uint32_t ucolor = color;
Vertex vert;
vert.pos = glm::vec2(x, y);
vert.color.r = (ucolor >> 16) & 0xFF;
vert.color.g = (ucolor >> 8) & 0xFF;
vert.color.b = ucolor & 0xFF;
_vbo.setData(sizeof(Vertex), &vert);
_vbo.bind(*_renderer);
vkCmdDraw(_renderer->getActiveCmdBuffer().get(), 1, 1, 0, 0);
}
void MLX_Window::endFrame()
{
_renderer->endFrame();
}
MLX_Window::~MLX_Window()
{
_vbo.destroy();
_renderer->destroy();
if(_win)
SDL_DestroyWindow(_win);
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/04 21:53:12 by maldavid #+# #+# */
/* Updated: 2022/12/18 03:41:53 by maldavid ### ########.fr */
/* Updated: 2022/12/19 00:40:26 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -15,6 +15,9 @@
#include <SDL2/SDL.h>
#include <string>
#include <memory>
#include <renderer/renderer.h>
#include <renderer/buffers/vk_vbo.h>
namespace mlx
{
@@ -26,11 +29,16 @@ namespace mlx
inline int& get_id() noexcept { return _id; }
inline SDL_Window* getNativeWindow() const noexcept { return _win; }
void pixel_put(int x, int y, int color) {}
bool beginFrame();
void endFrame();
void pixel_put(int x, int y, int color);
~MLX_Window();
private:
std::unique_ptr<Renderer> _renderer;
VBO _vbo;
SDL_Window* _win = nullptr;
int _id;
};

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:27:38 by maldavid #+# #+# */
/* Updated: 2022/12/18 02:51:53 by maldavid ### ########.fr */
/* Updated: 2022/12/18 20:10:12 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -14,6 +14,7 @@
#define __MLX_VK_VBO__
#include "vk_buffer.h"
#include <renderer/renderer.h>
namespace mlx
{
@@ -25,7 +26,7 @@ namespace mlx
void setData(uint32_t size, const void* data);
void setSubData(uint32_t offset, uint32_t size, const void* data);
inline void bind() noexcept { vkCmdBindVertexBuffers(Render_Core::get().getActiveCmdBuffer().get(), 0, 1, &_buffer, &_offset); }
inline void bind(Renderer& renderer) noexcept { vkCmdBindVertexBuffers(renderer.getActiveCmdBuffer().get(), 0, 1, &_buffer, &_offset); }
private:
uint32_t _used_size = 0;

View File

@@ -6,20 +6,23 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:26:06 by maldavid #+# #+# */
/* Updated: 2022/10/06 18:27:27 by maldavid ### ########.fr */
/* Updated: 2022/12/18 20:33:04 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include "vk_cmd_buffer.h"
#include <renderer/core/render_core.h>
#include <renderer/renderer.h>
namespace mlx
{
void CmdBuffer::init()
void CmdBuffer::init(Renderer* renderer)
{
_renderer = renderer;
VkCommandBufferAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
allocInfo.commandPool = Render_Core::get().getCmdPool().get();
allocInfo.commandPool = renderer->getCmdPool().get();
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocInfo.commandBufferCount = 1;
@@ -27,11 +30,6 @@ namespace mlx
core::error::report(e_kind::fatal_error, "Vulkan : failed to allocate command buffer");
}
void CmdBuffer::destroy() noexcept
{
vkFreeCommandBuffers(Render_Core::get().getDevice().get(), Render_Core::get().getCmdPool().get(), 1, &_cmd_buffer);
}
void CmdBuffer::beginRecord(VkCommandBufferUsageFlags usage)
{
if(_is_recording)
@@ -55,4 +53,9 @@ namespace mlx
_is_recording = false;
}
void CmdBuffer::destroy() noexcept
{
vkFreeCommandBuffers(Render_Core::get().getDevice().get(), _renderer->getCmdPool().get(), 1, &_cmd_buffer);
}
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:25:42 by maldavid #+# #+# */
/* Updated: 2022/12/18 01:08:34 by maldavid ### ########.fr */
/* Updated: 2022/12/18 20:32:45 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -20,7 +20,7 @@ namespace mlx
class CmdBuffer
{
public:
void init();
void init(class Renderer* renderer);
void destroy() noexcept;
void beginRecord(VkCommandBufferUsageFlags usage = 0);
@@ -31,6 +31,7 @@ namespace mlx
private:
VkCommandBuffer _cmd_buffer = VK_NULL_HANDLE;
class Renderer* _renderer = nullptr;
bool _is_recording = false;
};
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:24:33 by maldavid #+# #+# */
/* Updated: 2022/10/06 18:25:10 by maldavid ### ########.fr */
/* Updated: 2022/12/18 22:56:26 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -20,7 +20,7 @@ namespace mlx
VkCommandPoolCreateInfo poolInfo{};
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
poolInfo.queueFamilyIndex = Render_Core::get().getQueue().findQueueFamilies(Render_Core::get().getDevice().getPhysicalDevice()).graphicsFamily.value();
poolInfo.queueFamilyIndex = Render_Core::get().getQueue().getFamilies().graphicsFamily.value();
if(vkCreateCommandPool(Render_Core::get().getDevice().get(), &poolInfo, nullptr, &_cmd_pool) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create command pool");

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/12/17 23:33:34 by maldavid #+# #+# */
/* Updated: 2022/12/18 01:25:02 by maldavid ### ########.fr */
/* Updated: 2022/12/18 22:40:58 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -66,122 +66,16 @@ namespace mlx
}
}
Render_Core::Render_Core() : _device(), _queues(), _surface(),
_cmd_pool(), _swapchain(), _instance()
{}
void Render_Core::init()
{
volkInitialize();
_instance.init();
_surface.create();
_device.init();
_queues.init();
_swapchain.init();
_pass.init();
_swapchain.initFB();
_cmd_pool.init();
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
_cmd_buffers[i].init();
_semaphore.init();
_framebufferResized = false;
_is_init = true;
}
bool Render_Core::beginFrame()
{
if(!_is_init)
return false;
vkWaitForFences(_device(), 1, &_semaphore.getInFlightFence(_active_image_index), VK_TRUE, UINT64_MAX);
_image_index = 0;
VkResult result = vkAcquireNextImageKHR(_device(), _swapchain(), UINT64_MAX, _semaphore.getImageSemaphore(_active_image_index), 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");
vkResetFences(_device(), 1, &_semaphore.getInFlightFence(_active_image_index));
vkResetCommandBuffer(_cmd_buffers[_active_image_index].get(), 0);
_cmd_buffers[_active_image_index].beginRecord();
_pass.begin();
return true;
}
void Render_Core::endFrame()
{
if(!_is_init)
return;
_pass.end();
_cmd_buffers[_active_image_index].endRecord();
VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
VkSemaphore waitSemaphores[] = { _semaphore.getImageSemaphore(_active_image_index) };
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = waitSemaphores;
submitInfo.pWaitDstStageMask = waitStages;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &_cmd_buffers[_active_image_index].get();
VkSemaphore signalSemaphores[] = { _semaphore.getRenderImageSemaphore(_active_image_index) };
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = signalSemaphores;
if(vkQueueSubmit(_queues.getGraphic(), 1, &submitInfo, _semaphore.getInFlightFence(_active_image_index)) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan error : failed to submit draw command buffer");
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(_queues.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");
_active_image_index = (_active_image_index + 1) % MAX_FRAMES_IN_FLIGHT;
}
void Render_Core::destroyCommandBuffers()
{
std::mutex mutex;
std::unique_lock<std::mutex> watchdog(mutex, std::try_to_lock);
if(!_is_init)
return;
vkDeviceWaitIdle(_device());
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
_cmd_buffers[i].destroy();
}
void Render_Core::destroy()
{
std::mutex mutex;
@@ -192,13 +86,7 @@ namespace mlx
vkDeviceWaitIdle(_device());
_swapchain.destroyFB();
_pass.destroy();
_swapchain.destroy();
_semaphore.destroy();
_cmd_pool.destroy();
_device.destroy();
_surface.destroy();
_instance.destroy();
_is_init = false;

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 19:16:32 by maldavid #+# #+# */
/* Updated: 2022/12/18 03:42:51 by maldavid ### ########.fr */
/* Updated: 2022/12/18 17:51:47 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -14,19 +14,10 @@
#define __MLX_RENDER_CORE__
#include <volk.h>
#include <array>
#include <memory>
#include "vk_queues.h"
#include "vk_device.h"
#include "vk_surface.h"
#include "vk_instance.h"
#include "vk_semaphore.h"
#include <renderer/command/vk_cmd_pool.h>
#include <renderer/command/vk_cmd_buffer.h>
#include <renderer/swapchain/vk_swapchain.h>
#include <renderer/swapchain/vk_render_pass.h>
#include <utils/singleton.h>
#include <core/errors.h>
@@ -43,51 +34,21 @@ namespace mlx
class Render_Core : public Singleton<Render_Core>
{
public:
Render_Core();
Render_Core() = default;
void init();
void destroyCommandBuffers();
void destroy();
bool beginFrame();
void endFrame();
inline Instance& getInstance() noexcept { return _instance; }
inline Device& getDevice() noexcept { return _device; }
inline Queues& getQueue() noexcept { return _queues; }
inline std::shared_ptr<class MLX_Window> getWindow() { return _window; }
inline void setWindow(std::shared_ptr<class MLX_Window> window) { _window = window; }
inline Instance& getInstance() { return _instance; }
inline Device& getDevice() { return _device; }
inline Surface& getSurface() { return _surface; }
inline Queues& getQueue() { return _queues; }
inline CmdPool& getCmdPool() { return _cmd_pool; }
inline SwapChain& getSwapChain() { return _swapchain; }
inline Semaphore& getSemaphore() { return _semaphore; }
inline RenderPass& getRenderPass() { return _pass; }
inline CmdBuffer& getCmdBuffer(int i) { return _cmd_buffers[i]; }
inline CmdBuffer& getActiveCmdBuffer() { return _cmd_buffers[_active_image_index]; }
inline uint32_t getActiveImageIndex() { return _active_image_index; }
inline uint32_t getImageIndex() { return _image_index; }
constexpr inline void requireFrameBufferResize(int index) noexcept { _framebufferResized = true; }
~Render_Core() = default;
private:
Device _device;
Queues _queues;
Surface _surface;
RenderPass _pass;
CmdPool _cmd_pool;
Device _device;
Instance _instance;
SwapChain _swapchain;
Semaphore _semaphore;
std::array<CmdBuffer, MAX_FRAMES_IN_FLIGHT> _cmd_buffers;
std::shared_ptr<class MLX_Window> _window;
bool _framebufferResized = false;
uint32_t _active_image_index = 0;
uint32_t _image_index = 0;
bool _is_init = false;
};
}

View File

@@ -6,13 +6,16 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 19:14:29 by maldavid #+# #+# */
/* Updated: 2022/12/18 01:10:42 by maldavid ### ########.fr */
/* Updated: 2022/12/18 22:56:47 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include "render_core.h"
#include <vector>
#include <set>
#include <SDL2/SDL.h>
#include <SDL2/SDL_vulkan.h>
#include <iostream>
namespace mlx
{
@@ -22,7 +25,7 @@ namespace mlx
{
pickPhysicalDevice();
Queues::QueueFamilyIndices indices = Render_Core::get().getQueue().findQueueFamilies(_physicalDevice);
Queues::QueueFamilyIndices indices = Render_Core::get().getQueue().getFamilies();
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
std::set<uint32_t> uniqueQueueFamilies = { indices.graphicsFamily.value(), indices.presentFamily.value() };
@@ -67,33 +70,42 @@ namespace mlx
std::vector<VkPhysicalDevice> devices(deviceCount);
vkEnumeratePhysicalDevices(Render_Core::get().getInstance().get(), &deviceCount, devices.data());
SDL_Window* window = SDL_CreateWindow("", 0, 0, 1, 1, SDL_WINDOW_VULKAN | SDL_WINDOW_HIDDEN);
if(!window)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a window to pick physical device");
VkSurfaceKHR surface = VK_NULL_HANDLE;
if(SDL_Vulkan_CreateSurface(window, Render_Core::get().getInstance().get(), &surface) != SDL_TRUE)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a surface to pick physical device");
for(const auto& device : devices)
{
if(isDeviceSuitable(device))
if(isDeviceSuitable(device, surface))
{
_physicalDevice = device;
break;
}
}
vkDestroySurfaceKHR(Render_Core::get().getInstance().get(), surface, nullptr);
SDL_DestroyWindow(window);
if(_physicalDevice == VK_NULL_HANDLE)
core::error::report(e_kind::fatal_error, "Vulkan : failed to find a suitable GPU");
}
bool Device::isDeviceSuitable(VkPhysicalDevice device)
bool Device::isDeviceSuitable(VkPhysicalDevice device, VkSurfaceKHR surface)
{
Queues::QueueFamilyIndices indices = Render_Core::get().getQueue().findQueueFamilies(device);
Queues::QueueFamilyIndices indices = Render_Core::get().getQueue().findQueueFamilies(device, surface);
bool extensionsSupported = checkDeviceExtensionSupport(device);
bool swapChainAdequate = false;
uint32_t formatCount = 0;
if(extensionsSupported)
{
SwapChain::SwapChainSupportDetails swapChainSupport = Render_Core::get().getSwapChain().querySwapChainSupport(device);
swapChainAdequate = !swapChainSupport.formats.empty();
}
return indices.isComplete() && extensionsSupported && swapChainAdequate;
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, nullptr);
return indices.isComplete() && extensionsSupported && formatCount != 0;
}
bool Device::checkDeviceExtensionSupport(VkPhysicalDevice device)
{
uint32_t extensionCount;

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 19:13:42 by maldavid #+# #+# */
/* Updated: 2022/12/18 01:08:11 by maldavid ### ########.fr */
/* Updated: 2022/12/18 22:55:30 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -14,6 +14,7 @@
#define __MLX_VK_DEVICE__
#include <volk.h>
#include "vk_queues.h"
namespace mlx
{
@@ -30,7 +31,7 @@ namespace mlx
private:
void pickPhysicalDevice();
bool isDeviceSuitable(VkPhysicalDevice device);
bool isDeviceSuitable(VkPhysicalDevice device, VkSurfaceKHR surface);
bool checkDeviceExtensionSupport(VkPhysicalDevice device);
VkPhysicalDevice _physicalDevice = VK_NULL_HANDLE;

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 19:04:21 by maldavid #+# #+# */
/* Updated: 2022/12/18 00:34:58 by maldavid ### ########.fr */
/* Updated: 2022/12/18 22:37:00 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -23,9 +23,9 @@ namespace mlx
{
VkApplicationInfo appInfo{};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "MicroLibX";
appInfo.pApplicationName = "MacroLibX";
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.pEngineName = "MicroLibX";
appInfo.pEngineName = "MacroLibX";
appInfo.engineVersion = VK_MAKE_VERSION(0, 0, 1);
appInfo.apiVersion = VK_API_VERSION_1_2;
@@ -44,20 +44,27 @@ namespace mlx
VkResult res;
if((res = vkCreateInstance(&createInfo, nullptr, &_instance)) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create Vulkan instance : %s", RCore::verbaliseResultVk(res));
volkLoadInstance(_instance);
}
std::vector<const char*> Instance::getRequiredExtensions()
{
unsigned int count = 0;
if(!SDL_Vulkan_GetInstanceExtensions(Render_Core::get().getWindow()->getNativeWindow(), &count, nullptr))
SDL_Window* window = SDL_CreateWindow("", 0, 0, 1, 1, SDL_WINDOW_VULKAN | SDL_WINDOW_HIDDEN);
if(!window)
core::error::report(e_kind::fatal_error, "Vulkan : cannot get instance extentions from window : %s", SDL_GetError());
if(!SDL_Vulkan_GetInstanceExtensions(window, &count, nullptr))
core::error::report(e_kind::fatal_error, "Vulkan : cannot get instance extentions from window : %s", SDL_GetError());
std::vector<const char*> extensions = { VK_EXT_DEBUG_REPORT_EXTENSION_NAME };
size_t additional_extension_count = extensions.size();
extensions.resize(additional_extension_count + count);
if(!SDL_Vulkan_GetInstanceExtensions(Render_Core::get().getWindow()->getNativeWindow(), &count, extensions.data() + additional_extension_count))
if(!SDL_Vulkan_GetInstanceExtensions(window, &count, extensions.data() + additional_extension_count))
core::error::report(e_kind::error, "Vulkan : cannot get instance extentions from window : %s", SDL_GetError());
SDL_DestroyWindow(window);
return extensions;
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 19:03:04 by maldavid #+# #+# */
/* Updated: 2022/12/18 01:08:07 by maldavid ### ########.fr */
/* Updated: 2022/12/18 17:42:08 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -21,7 +21,6 @@ namespace mlx
class Instance
{
public:
void init();
void destroy() noexcept;

View File

@@ -6,15 +6,17 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 19:02:42 by maldavid #+# #+# */
/* Updated: 2022/10/08 19:02:52 by maldavid ### ########.fr */
/* Updated: 2022/12/18 22:52:04 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include "render_core.h"
#include <SDL2/SDL.h>
#include <SDL2/SDL_vulkan.h>
namespace mlx
{
Queues::QueueFamilyIndices Queues::findQueueFamilies(VkPhysicalDevice device)
Queues::QueueFamilyIndices Queues::findQueueFamilies(VkPhysicalDevice device, VkSurfaceKHR surface)
{
uint32_t queueFamilyCount = 0;
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);
@@ -23,7 +25,6 @@ namespace mlx
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());
_families = Queues::QueueFamilyIndices{};
int i = 0;
for(const auto& queueFamily : queueFamilies)
{
@@ -31,7 +32,7 @@ namespace mlx
_families->graphicsFamily = i;
VkBool32 presentSupport = false;
vkGetPhysicalDeviceSurfaceSupportKHR(device, i, Render_Core::get().getSurface().get(), &presentSupport);
vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);
if(presentSupport)
_families->presentFamily = i;
@@ -40,13 +41,27 @@ namespace mlx
break;
i++;
}
return *_families;
}
void Queues::init()
{
if(!_families.has_value())
findQueueFamilies(Render_Core::get().getDevice().getPhysicalDevice());
{
SDL_Window* window = SDL_CreateWindow("", 0, 0, 1, 1, SDL_WINDOW_VULKAN | SDL_WINDOW_HIDDEN);
if(!window)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a window to init queues");
VkSurfaceKHR surface = VK_NULL_HANDLE;
if(SDL_Vulkan_CreateSurface(window, Render_Core::get().getInstance().get(), &surface) != SDL_TRUE)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a surface to init queues");
findQueueFamilies(Render_Core::get().getDevice().getPhysicalDevice(), surface);
vkDestroySurfaceKHR(Render_Core::get().getInstance().get(), surface, nullptr);
SDL_DestroyWindow(window);
}
vkGetDeviceQueue(Render_Core::get().getDevice().get(), _families->graphicsFamily.value(), 0, &_graphicsQueue);
vkGetDeviceQueue(Render_Core::get().getDevice().get(), _families->presentFamily.value(), 0, &_presentQueue);
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 19:01:49 by maldavid #+# #+# */
/* Updated: 2022/12/18 01:08:04 by maldavid ### ########.fr */
/* Updated: 2022/12/18 22:44:37 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -30,7 +30,7 @@ namespace mlx
inline bool isComplete() { return graphicsFamily.has_value() && presentFamily.has_value(); }
};
QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device);
QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device, VkSurfaceKHR surface);
void init();

View File

@@ -6,21 +6,22 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 19:01:08 by maldavid #+# #+# */
/* Updated: 2022/10/08 19:01:44 by maldavid ### ########.fr */
/* Updated: 2022/12/18 20:12:40 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include "vk_semaphore.h"
#include "render_core.h"
#include <renderer/renderer.h>
namespace mlx
{
void Semaphore::init()
void Semaphore::init(Renderer& renderer)
{
_imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
_renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
_inFlightFences.resize(MAX_FRAMES_IN_FLIGHT);
_imagesInFlight.resize(Render_Core::get().getSwapChain().getImagesNumber(), VK_NULL_HANDLE);
_imagesInFlight.resize(renderer.getSwapChain().getImagesNumber(), VK_NULL_HANDLE);
VkSemaphoreCreateInfo semaphoreInfo{};
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 18:59:38 by maldavid #+# #+# */
/* Updated: 2022/12/18 01:08:00 by maldavid ### ########.fr */
/* Updated: 2022/12/18 19:50:10 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -21,7 +21,7 @@ namespace mlx
class Semaphore
{
public:
void init();
void init(class Renderer& renderer);
void destroy() noexcept;
inline VkSemaphore& getImageSemaphore(int i) noexcept { return _imageAvailableSemaphores[i]; }

View File

@@ -6,20 +6,22 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 18:58:49 by maldavid #+# #+# */
/* Updated: 2022/12/18 00:35:03 by maldavid ### ########.fr */
/* Updated: 2022/12/18 22:20:57 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include "render_core.h"
#include <platform/window.h>
#include <renderer/renderer.h>
#include <SDL2/SDL_vulkan.h>
#include <SDL2/SDL.h>
namespace mlx
{
void Surface::create()
void Surface::create(Renderer& renderer)
{
if(SDL_Vulkan_CreateSurface(Render_Core::get().getWindow()->getNativeWindow(), Render_Core::get().getInstance().get(), &_surface) != SDL_TRUE)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a surface");
if(SDL_Vulkan_CreateSurface(renderer.getWindow()->getNativeWindow(), Render_Core::get().getInstance().get(), &_surface) != SDL_TRUE)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a surface : %s", SDL_GetError());
}
VkSurfaceFormatKHR Surface::chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats)

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/08 18:57:55 by maldavid #+# #+# */
/* Updated: 2022/12/18 01:07:57 by maldavid ### ########.fr */
/* Updated: 2022/12/18 19:34:04 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -21,7 +21,7 @@ namespace mlx
class Surface
{
public:
void create();
void create(class Renderer& renderer);
void destroy() noexcept;
VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats);

215
src/renderer/pipeline/pipeline.cpp git.filemode.normal_file
View File

@@ -0,0 +1,215 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* pipeline.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/12/18 21:27:38 by maldavid #+# #+# */
/* Updated: 2022/12/19 00:26:39 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include "pipeline.h"
#include <renderer/renderer.h>
#include <renderer/core/render_core.h>
namespace mlx
{
const std::vector<uint32_t> vertex_shader = {
0x07230203,0x00010000,0x0008000a,0x00000021,0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
0x0009000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000000d,0x00000012,0x0000001d,
0x0000001f,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d,0x00000000,
0x00060005,0x0000000b,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,0x0000000b,
0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x0000000b,0x00000001,0x505f6c67,
0x746e696f,0x657a6953,0x00000000,0x00070006,0x0000000b,0x00000002,0x435f6c67,0x4470696c,
0x61747369,0x0065636e,0x00070006,0x0000000b,0x00000003,0x435f6c67,0x446c6c75,0x61747369,
0x0065636e,0x00030005,0x0000000d,0x00000000,0x00050005,0x00000012,0x6f506e69,0x69746973,
0x00006e6f,0x00050005,0x0000001d,0x67617266,0x6f6c6f43,0x00000072,0x00040005,0x0000001f,
0x6f436e69,0x00726f6c,0x00050048,0x0000000b,0x00000000,0x0000000b,0x00000000,0x00050048,
0x0000000b,0x00000001,0x0000000b,0x00000001,0x00050048,0x0000000b,0x00000002,0x0000000b,
0x00000003,0x00050048,0x0000000b,0x00000003,0x0000000b,0x00000004,0x00030047,0x0000000b,
0x00000002,0x00040047,0x00000012,0x0000001e,0x00000000,0x00040047,0x0000001d,0x0000001e,
0x00000000,0x00040047,0x0000001f,0x0000001e,0x00000001,0x00020013,0x00000002,0x00030021,
0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,
0x00000004,0x00040015,0x00000008,0x00000020,0x00000000,0x0004002b,0x00000008,0x00000009,
0x00000001,0x0004001c,0x0000000a,0x00000006,0x00000009,0x0006001e,0x0000000b,0x00000007,
0x00000006,0x0000000a,0x0000000a,0x00040020,0x0000000c,0x00000003,0x0000000b,0x0004003b,
0x0000000c,0x0000000d,0x00000003,0x00040015,0x0000000e,0x00000020,0x00000001,0x0004002b,
0x0000000e,0x0000000f,0x00000000,0x00040017,0x00000010,0x00000006,0x00000002,0x00040020,
0x00000011,0x00000001,0x00000010,0x0004003b,0x00000011,0x00000012,0x00000001,0x0004002b,
0x00000006,0x00000014,0x00000000,0x0004002b,0x00000006,0x00000015,0x3f800000,0x00040020,
0x00000019,0x00000003,0x00000007,0x00040017,0x0000001b,0x00000006,0x00000003,0x00040020,
0x0000001c,0x00000003,0x0000001b,0x0004003b,0x0000001c,0x0000001d,0x00000003,0x00040020,
0x0000001e,0x00000001,0x0000001b,0x0004003b,0x0000001e,0x0000001f,0x00000001,0x00050036,
0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x00000010,
0x00000013,0x00000012,0x00050051,0x00000006,0x00000016,0x00000013,0x00000000,0x00050051,
0x00000006,0x00000017,0x00000013,0x00000001,0x00070050,0x00000007,0x00000018,0x00000016,
0x00000017,0x00000014,0x00000015,0x00050041,0x00000019,0x0000001a,0x0000000d,0x0000000f,
0x0003003e,0x0000001a,0x00000018,0x0004003d,0x0000001b,0x00000020,0x0000001f,0x0003003e,
0x0000001d,0x00000020,0x000100fd,0x00010038
};
const std::vector<uint32_t> fragment_shader = {
0x07230203,0x00010000,0x0008000a,0x00000013,0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000009,0x0000000c,0x00030010,
0x00000004,0x00000007,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d,
0x00000000,0x00050005,0x00000009,0x4374756f,0x726f6c6f,0x00000000,0x00050005,0x0000000c,
0x67617266,0x6f6c6f43,0x00000072,0x00040047,0x00000009,0x0000001e,0x00000000,0x00040047,
0x0000000c,0x0000001e,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,
0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040020,
0x00000008,0x00000003,0x00000007,0x0004003b,0x00000008,0x00000009,0x00000003,0x00040017,
0x0000000a,0x00000006,0x00000003,0x00040020,0x0000000b,0x00000001,0x0000000a,0x0004003b,
0x0000000b,0x0000000c,0x00000001,0x0004002b,0x00000006,0x0000000e,0x3f800000,0x00050036,
0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003d,0x0000000a,
0x0000000d,0x0000000c,0x00050051,0x00000006,0x0000000f,0x0000000d,0x00000000,0x00050051,
0x00000006,0x00000010,0x0000000d,0x00000001,0x00050051,0x00000006,0x00000011,0x0000000d,
0x00000002,0x00070050,0x00000007,0x00000012,0x0000000f,0x00000010,0x00000011,0x0000000e,
0x0003003e,0x00000009,0x00000012,0x000100fd,0x00010038
};
void GraphicPipeline::init(Renderer& renderer)
{
std::vector<VkPipelineShaderStageCreateInfo> stages;
VkShaderModuleCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
createInfo.codeSize = vertex_shader.size();
createInfo.pCode = vertex_shader.data();
VkShaderModule vshader;
if(vkCreateShaderModule(Render_Core::get().getDevice().get(), &createInfo, nullptr, &vshader) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a vertex shader module");
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
createInfo.codeSize = fragment_shader.size();
createInfo.pCode = fragment_shader.data();
VkShaderModule fshader;
if(vkCreateShaderModule(Render_Core::get().getDevice().get(), &createInfo, nullptr, &fshader) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a fragment shader module");
VkPipelineShaderStageCreateInfo vertShaderStageInfo{};
vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
vertShaderStageInfo.module = vshader;
vertShaderStageInfo.pName = "main";
VkPipelineShaderStageCreateInfo fragShaderStageInfo{};
fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
fragShaderStageInfo.module = fshader;
fragShaderStageInfo.pName = "main";
VkPipelineShaderStageCreateInfo shaderStages[] = {vertShaderStageInfo, fragShaderStageInfo};
auto bindingDescription = Vertex::getBindingDescription();
auto attributeDescriptions = Vertex::getAttributeDescriptions();
VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo{};
vertexInputStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertexInputStateCreateInfo.vertexBindingDescriptionCount = 1;
vertexInputStateCreateInfo.pVertexBindingDescriptions = &bindingDescription;
vertexInputStateCreateInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(attributeDescriptions.size());
vertexInputStateCreateInfo.pVertexAttributeDescriptions = attributeDescriptions.data();
VkPipelineInputAssemblyStateCreateInfo inputAssembly{};
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
inputAssembly.primitiveRestartEnable = VK_FALSE;
VkDynamicState states[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
constexpr size_t statesCount = sizeof(states) / sizeof(VkDynamicState);
VkPipelineDynamicStateCreateInfo dynamicStates{};
dynamicStates.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
dynamicStates.dynamicStateCount = statesCount;
dynamicStates.pDynamicStates = states;
VkViewport viewport{};
viewport.x = 0.0f;
viewport.y = 0.0f;
viewport.width = (float)renderer.getSwapChain()._swapChainExtent.width;
viewport.height = (float)renderer.getSwapChain()._swapChainExtent.height;
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
VkRect2D scissor{};
scissor.offset = { 0, 0 };
scissor.extent = renderer.getSwapChain()._swapChainExtent;
VkPipelineViewportStateCreateInfo viewportState{};
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
viewportState.viewportCount = 1;
viewportState.pViewports = &viewport;
viewportState.scissorCount = 1;
viewportState.pScissors = &scissor;
VkPipelineRasterizationStateCreateInfo rasterizer{};
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
rasterizer.depthClampEnable = VK_FALSE;
rasterizer.rasterizerDiscardEnable = VK_FALSE;
rasterizer.polygonMode = VK_POLYGON_MODE_POINT;
rasterizer.lineWidth = 1.0f;
rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
rasterizer.depthBiasEnable = VK_FALSE;
VkPipelineMultisampleStateCreateInfo multisampling{};
multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
multisampling.sampleShadingEnable = VK_FALSE;
multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
VkPipelineColorBlendAttachmentState colorBlendAttachment{};
colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
colorBlendAttachment.blendEnable = VK_FALSE;
VkPipelineColorBlendStateCreateInfo colorBlending{};
colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
colorBlending.logicOpEnable = VK_FALSE;
colorBlending.logicOp = VK_LOGIC_OP_COPY;
colorBlending.attachmentCount = 1;
colorBlending.pAttachments = &colorBlendAttachment;
colorBlending.blendConstants[0] = 0.0f;
colorBlending.blendConstants[1] = 0.0f;
colorBlending.blendConstants[2] = 0.0f;
colorBlending.blendConstants[3] = 0.0f;
VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.setLayoutCount = 0;
pipelineLayoutInfo.pSetLayouts = 0;
if(vkCreatePipelineLayout(Render_Core::get().getDevice().get(), &pipelineLayoutInfo, nullptr, &_pipelineLayout) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a graphics pipeline layout");
VkGraphicsPipelineCreateInfo pipelineInfo{};
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
pipelineInfo.stageCount = stages.size();
pipelineInfo.pStages = stages.data();
pipelineInfo.pVertexInputState = &vertexInputStateCreateInfo;
pipelineInfo.pInputAssemblyState = &inputAssembly;
pipelineInfo.pViewportState = &viewportState;
pipelineInfo.pRasterizationState = &rasterizer;
pipelineInfo.pMultisampleState = &multisampling;
pipelineInfo.pColorBlendState = &colorBlending;
pipelineInfo.pDynamicState = &dynamicStates;
pipelineInfo.layout = _pipelineLayout;
pipelineInfo.renderPass = renderer.getRenderPass().get();
pipelineInfo.subpass = 0;
pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
if(vkCreateGraphicsPipelines(Render_Core::get().getDevice().get(), VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &_graphicsPipeline) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a graphics pipeline");
vkDestroyShaderModule(Render_Core::get().getDevice().get(), fshader, nullptr);
vkDestroyShaderModule(Render_Core::get().getDevice().get(), vshader, nullptr);
}
void GraphicPipeline::destroy() noexcept
{
vkDestroyPipeline(Render_Core::get().getDevice().get(), _graphicsPipeline, nullptr);
vkDestroyPipelineLayout(Render_Core::get().getDevice().get(), _pipelineLayout, nullptr);
}
}

39
src/renderer/pipeline/pipeline.h git.filemode.normal_file
View File

@@ -0,0 +1,39 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* pipeline.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/12/18 21:23:52 by maldavid #+# #+# */
/* Updated: 2022/12/19 00:27:29 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef __PIPELINE__
#define __PIPELINE__
#include <volk.h>
#include <renderer/command/vk_cmd_buffer.h>
namespace mlx
{
class GraphicPipeline
{
public:
void init(class Renderer& renderer);
void destroy() noexcept;
inline void bindPipeline(CmdBuffer& commandBuffer) noexcept { vkCmdBindPipeline(commandBuffer.get(), VK_PIPELINE_BIND_POINT_GRAPHICS, _graphicsPipeline); }
inline const VkPipeline& getPipeline() const noexcept { return _graphicsPipeline; }
inline const VkPipelineLayout& getPipelineLayout() const noexcept { return _pipelineLayout; }
private:
VkPipeline _graphicsPipeline = VK_NULL_HANDLE;
VkPipelineCache _cache = VK_NULL_HANDLE;
VkPipelineLayout _pipelineLayout = VK_NULL_HANDLE;
};
}
#endif

144
src/renderer/renderer.cpp git.filemode.normal_file
View File

@@ -0,0 +1,144 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* renderer.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/12/18 17:25:16 by maldavid #+# #+# */
/* Updated: 2022/12/19 00:00:46 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <mutex>
#include <renderer/renderer.h>
#include <renderer/core/render_core.h>
namespace mlx
{
void Renderer::init()
{
_surface.create(*this);
_swapchain.init(this);
_pass.init(this);
_swapchain.initFB();
_cmd_pool.init();
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
_cmd_buffers[i].init(this);
_semaphore.init(*this);
_pipeline.init(*this);
_framebufferResized = false;
}
bool Renderer::beginFrame()
{
auto device = Render_Core::get().getDevice().get();
vkWaitForFences(device, 1, &_semaphore.getInFlightFence(_active_image_index), VK_TRUE, UINT64_MAX);
_image_index = 0;
VkResult result = vkAcquireNextImageKHR(device, _swapchain(), UINT64_MAX, _semaphore.getImageSemaphore(_active_image_index), 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");
vkResetFences(device, 1, &_semaphore.getInFlightFence(_active_image_index));
vkResetCommandBuffer(_cmd_buffers[_active_image_index].get(), 0);
_cmd_buffers[_active_image_index].beginRecord();
_pass.begin();
_pipeline.bindPipeline(_cmd_buffers[_active_image_index]);
VkViewport viewport{};
viewport.x = 0.0f;
viewport.y = 0.0f;
viewport.width = (float)_swapchain._swapChainExtent.width;
viewport.height = (float)_swapchain._swapChainExtent.height;
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
vkCmdSetViewport(_cmd_buffers[_active_image_index].get(), 0, 1, &viewport);
VkRect2D scissor{};
scissor.offset = { 0, 0 };
scissor.extent = _swapchain._swapChainExtent;
vkCmdSetScissor(_cmd_buffers[_active_image_index].get(), 0, 1, &scissor);
return true;
}
void Renderer::endFrame()
{
_pass.end();
_cmd_buffers[_active_image_index].endRecord();
VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
VkSemaphore waitSemaphores[] = { _semaphore.getImageSemaphore(_active_image_index) };
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = waitSemaphores;
submitInfo.pWaitDstStageMask = waitStages;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &_cmd_buffers[_active_image_index].get();
VkSemaphore signalSemaphores[] = { _semaphore.getRenderImageSemaphore(_active_image_index) };
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = signalSemaphores;
if(vkQueueSubmit(Render_Core::get().getQueue().getGraphic(), 1, &submitInfo, _semaphore.getInFlightFence(_active_image_index)) != VK_SUCCESS)
core::error::report(e_kind::fatal_error, "Vulkan error : failed to submit draw command buffer");
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");
_active_image_index = (_active_image_index + 1) % MAX_FRAMES_IN_FLIGHT;
}
void Renderer::destroy()
{
std::mutex mutex;
std::unique_lock<std::mutex> watchdog(mutex, std::try_to_lock);
vkDeviceWaitIdle(Render_Core::get().getDevice().get());
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
_cmd_buffers[i].destroy();
_swapchain.destroyFB();
_pass.destroy();
_swapchain.destroy();
_semaphore.destroy();
_cmd_pool.destroy();
_surface.destroy();
}
}

114
src/renderer/renderer.h git.filemode.normal_file
View File

@@ -0,0 +1,114 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* renderer.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/12/18 17:14:45 by maldavid #+# #+# */
/* Updated: 2022/12/18 22:15:50 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef __RENDERER__
#define __RENDERER__
#include <array>
#include <vector>
#include <memory>
#include <renderer/core/vk_surface.h>
#include <renderer/core/render_core.h>
#include <renderer/core/vk_semaphore.h>
#include <renderer/pipeline/pipeline.h>
#include <renderer/command/vk_cmd_pool.h>
#include <renderer/command/vk_cmd_buffer.h>
#include <renderer/swapchain/vk_swapchain.h>
#include <renderer/swapchain/vk_render_pass.h>
#include <core/errors.h>
#include <glm/glm.hpp>
namespace mlx
{
struct Vertex
{
glm::vec2 pos;
glm::vec3 color;
static VkVertexInputBindingDescription getBindingDescription()
{
VkVertexInputBindingDescription bindingDescription{};
bindingDescription.binding = 0;
bindingDescription.stride = sizeof(Vertex);
bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
return bindingDescription;
}
static std::array<VkVertexInputAttributeDescription, 2> getAttributeDescriptions()
{
std::array<VkVertexInputAttributeDescription, 2> attributeDescriptions;
attributeDescriptions[0].binding = 0;
attributeDescriptions[0].location = 0;
attributeDescriptions[0].format = VK_FORMAT_R32G32_SFLOAT;
attributeDescriptions[0].offset = offsetof(Vertex, pos);
attributeDescriptions[1].binding = 0;
attributeDescriptions[1].location = 1;
attributeDescriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDescriptions[1].offset = offsetof(Vertex, color);
return attributeDescriptions;
}
};
class Renderer
{
public:
Renderer() = default;
void init();
bool beginFrame();
void endFrame();
void destroy();
inline class MLX_Window* getWindow() { return _window; }
inline void setWindow(class MLX_Window* window) { _window = window; }
inline Surface& getSurface() noexcept { return _surface; }
inline CmdPool& getCmdPool() noexcept { return _cmd_pool; }
inline SwapChain& getSwapChain() noexcept { return _swapchain; }
inline Semaphore& getSemaphore() noexcept { return _semaphore; }
inline RenderPass& getRenderPass() noexcept { return _pass; }
inline CmdBuffer& getCmdBuffer(int i) noexcept { return _cmd_buffers[i]; }
inline CmdBuffer& getActiveCmdBuffer() noexcept { return _cmd_buffers[_active_image_index]; }
inline uint32_t getActiveImageIndex() noexcept { return _active_image_index; }
inline uint32_t getImageIndex() noexcept { return _image_index; }
constexpr inline void requireFrameBufferResize(int index) noexcept { _framebufferResized = true; }
~Renderer() = default;
private:
GraphicPipeline _pipeline;
RenderPass _pass;
Surface _surface;
CmdPool _cmd_pool;
SwapChain _swapchain;
Semaphore _semaphore;
std::array<CmdBuffer, MAX_FRAMES_IN_FLIGHT> _cmd_buffers;
class MLX_Window* _window;
uint32_t _active_image_index = 0;
uint32_t _image_index = 0;
bool _framebufferResized = false;
};
}
#endif

View File

@@ -6,26 +6,27 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:18:06 by maldavid #+# #+# */
/* Updated: 2022/12/17 23:34:57 by maldavid ### ########.fr */
/* Updated: 2022/12/18 20:01:51 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <volk.h>
#include <renderer/core/render_core.h>
#include <renderer/renderer.h>
namespace mlx
{
void FrameBuffer::init(SwapChain* swapchain, ImageView& image)
void FrameBuffer::init(Renderer& renderer, ImageView& image)
{
VkImageView attachments[] = { image() };
VkFramebufferCreateInfo framebufferInfo{};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferInfo.renderPass = Render_Core::get().getRenderPass().get();
framebufferInfo.renderPass = renderer.getRenderPass().get();
framebufferInfo.attachmentCount = 1;
framebufferInfo.pAttachments = attachments;
framebufferInfo.width = swapchain->_swapChainExtent.width;
framebufferInfo.height = swapchain->_swapChainExtent.height;
framebufferInfo.width = renderer.getSwapChain()._swapChainExtent.width;
framebufferInfo.height = renderer.getSwapChain()._swapChainExtent.height;
framebufferInfo.layers = 1;
if(vkCreateFramebuffer(Render_Core::get().getDevice().get(), &framebufferInfo, nullptr, &_framebuffer) != VK_SUCCESS)

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:19:44 by maldavid #+# #+# */
/* Updated: 2022/12/18 01:07:54 by maldavid ### ########.fr */
/* Updated: 2022/12/18 19:53:00 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -20,7 +20,7 @@ namespace mlx
class FrameBuffer
{
public:
void init(class SwapChain* swapchain, class ImageView& image);
void init(class Renderer& renderer, class ImageView& image);
void destroy() noexcept;
inline VkFramebuffer& operator()() noexcept { return _framebuffer; }

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:20:49 by maldavid #+# #+# */
/* Updated: 2022/10/06 18:21:51 by maldavid ### ########.fr */
/* Updated: 2022/12/18 19:55:03 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -16,13 +16,13 @@
namespace mlx
{
void ImageView::init(SwapChain* swapchain, VkImage& image)
void ImageView::init(SwapChain& swapchain, VkImage& image)
{
VkImageViewCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
createInfo.image = image;
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
createInfo.format = swapchain->_swapChainImageFormat;
createInfo.format = swapchain._swapChainImageFormat;
createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:20:19 by maldavid #+# #+# */
/* Updated: 2022/12/18 01:07:51 by maldavid ### ########.fr */
/* Updated: 2022/12/18 19:54:44 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -20,7 +20,7 @@ namespace mlx
class ImageView
{
public:
void init(class SwapChain* swapchain, VkImage& image);
void init(class SwapChain& swapchain, VkImage& image);
void destroy() noexcept;
inline VkImageView& operator()() noexcept { return _image; }

View File

@@ -6,19 +6,24 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:21:36 by maldavid #+# #+# */
/* Updated: 2022/12/18 01:13:49 by maldavid ### ########.fr */
/* Updated: 2022/12/19 00:06:34 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include "vk_render_pass.h"
#include <renderer/core/render_core.h>
#include <renderer/renderer.h>
namespace mlx
{
void RenderPass::init()
static const VkClearValue clearColor = { 0.0f, 0.0f, 0.0f, 1.0f };
void RenderPass::init(Renderer* renderer)
{
_renderer = renderer;
VkAttachmentDescription colorAttachment{};
colorAttachment.format = Render_Core::get().getSwapChain()._swapChainImageFormat;
colorAttachment.format = renderer->getSwapChain()._swapChainImageFormat;
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
@@ -52,18 +57,16 @@ namespace mlx
if(_is_running)
return;
static const VkClearValue clearColor = {0.0f, 0.0f, 0.0f, 1.0f};
VkRenderPassBeginInfo renderPassInfo{};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassInfo.renderPass = _renderPass;
renderPassInfo.framebuffer = Render_Core::get().getSwapChain()._framebuffers[Render_Core::get().getImageIndex()].get();
renderPassInfo.framebuffer = _renderer->getSwapChain()._framebuffers[_renderer->getImageIndex()].get();
renderPassInfo.renderArea.offset = { 0, 0 };
renderPassInfo.renderArea.extent = Render_Core::get().getSwapChain()._swapChainExtent;
renderPassInfo.renderArea.extent = _renderer->getSwapChain()._swapChainExtent;
renderPassInfo.clearValueCount = 1;
renderPassInfo.pClearValues = &clearColor;
vkCmdBeginRenderPass(Render_Core::get().getActiveCmdBuffer().get(), &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdBeginRenderPass(_renderer->getActiveCmdBuffer().get(), &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
_is_running = true;
}
@@ -73,7 +76,7 @@ namespace mlx
if(!_is_running)
return;
vkCmdEndRenderPass(Render_Core::get().getActiveCmdBuffer().get());
vkCmdEndRenderPass(_renderer->getActiveCmdBuffer().get());
_is_running = false;
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:22:00 by maldavid #+# #+# */
/* Updated: 2022/12/18 01:07:47 by maldavid ### ########.fr */
/* Updated: 2022/12/18 20:33:28 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -20,7 +20,7 @@ namespace mlx
class RenderPass
{
public:
void init();
void init(class Renderer* renderer);
void destroy() noexcept;
void begin();
@@ -31,6 +31,7 @@ namespace mlx
private:
VkRenderPass _renderPass = VK_NULL_HANDLE;
class Renderer* _renderer = nullptr;
bool _is_running = false;
};
}

View File

@@ -6,22 +6,25 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:22:28 by maldavid #+# #+# */
/* Updated: 2022/12/18 01:01:32 by maldavid ### ########.fr */
/* Updated: 2022/12/19 00:05:32 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
#include <renderer/core/render_core.h>
#include <renderer/renderer.h>
#include <platform/window.h>
#include <SDL2/SDL_vulkan.h>
#include <algorithm>
namespace mlx
{
void SwapChain::init()
void SwapChain::init(Renderer* renderer)
{
_renderer = renderer;
_swapChainSupport = querySwapChainSupport(Render_Core::get().getDevice().getPhysicalDevice());
VkSurfaceFormatKHR surfaceFormat = Render_Core::get().getSurface().chooseSwapSurfaceFormat(_swapChainSupport.formats);
VkSurfaceFormatKHR surfaceFormat = renderer->getSurface().chooseSwapSurfaceFormat(_swapChainSupport.formats);
VkPresentModeKHR presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
VkExtent2D extent = chooseSwapExtent(_swapChainSupport.capabilities);
@@ -31,7 +34,7 @@ namespace mlx
VkSwapchainCreateInfoKHR createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
createInfo.surface = Render_Core::get().getSurface().get();
createInfo.surface = renderer->getSurface().get();
createInfo.minImageCount = imageCount;
createInfo.imageFormat = surfaceFormat.format;
@@ -40,7 +43,7 @@ namespace mlx
createInfo.imageArrayLayers = 1;
createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
Queues::QueueFamilyIndices indices = Render_Core::get().getQueue().findQueueFamilies(Render_Core::get().getDevice().getPhysicalDevice());
Queues::QueueFamilyIndices indices = Render_Core::get().getQueue().getFamilies();
uint32_t queueFamilyIndices[] = {indices.graphicsFamily.value(), indices.presentFamily.value()};
if(indices.graphicsFamily != indices.presentFamily)
@@ -74,10 +77,7 @@ namespace mlx
_imageViews.resize(_swapChainImages.size());
for(size_t i = 0; i < _swapChainImages.size(); i++)
{
_imageViews.emplace_back();
_imageViews.back().init(this, _swapChainImages[i]);
}
_imageViews[i].init(*this, _swapChainImages[i]);
}
void SwapChain::initFB()
@@ -85,16 +85,13 @@ namespace mlx
_framebuffers.resize(_imageViews.size());
for(size_t i = 0; i < _imageViews.size(); i++)
{
_framebuffers.emplace_back();
_framebuffers.back().init(this, _imageViews[i]);
}
_framebuffers[i].init(*_renderer, _imageViews[i]);
}
SwapChain::SwapChainSupportDetails SwapChain::querySwapChainSupport(VkPhysicalDevice device)
{
SwapChain::SwapChainSupportDetails details;
VkSurfaceKHR surface = Render_Core::get().getSurface().get();
VkSurfaceKHR surface = _renderer->getSurface().get();
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &details.capabilities);
@@ -115,7 +112,7 @@ namespace mlx
return capabilities.currentExtent;
int width, height;
SDL_Vulkan_GetDrawableSize(Render_Core::get().getWindow()->getNativeWindow(), &width, &height);
SDL_Vulkan_GetDrawableSize(_renderer->getWindow()->getNativeWindow(), &width, &height);
VkExtent2D actualExtent = { static_cast<uint32_t>(width), static_cast<uint32_t>(height) };
@@ -129,10 +126,10 @@ namespace mlx
{
destroyFB();
destroy();
Render_Core::get().getRenderPass().destroy();
_renderer->getRenderPass().destroy();
init();
Render_Core::get().getRenderPass().init();
init(_renderer);
_renderer->getRenderPass().init(_renderer);
initFB();
}

View File

@@ -6,7 +6,7 @@
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2022/10/06 18:23:27 by maldavid #+# #+# */
/* Updated: 2022/12/18 01:07:44 by maldavid ### ########.fr */
/* Updated: 2022/12/18 22:08:36 by maldavid ### ########.fr */
/* */
/* ************************************************************************** */
@@ -26,7 +26,7 @@ namespace mlx
friend class ImageView;
friend class GraphicPipeline;
friend class RenderPass;
friend class RendererComponent;
friend class Renderer;
public:
struct SwapChainSupportDetails
@@ -35,7 +35,7 @@ namespace mlx
std::vector<VkSurfaceFormatKHR> formats;
};
void init();
void init(class Renderer* renderer);
void initFB();
void destroy() noexcept;
void destroyFB() noexcept;
@@ -53,12 +53,13 @@ namespace mlx
private:
SwapChainSupportDetails _swapChainSupport;
VkSwapchainKHR _swapChain;
std::vector<VkImage> _swapChainImages;
VkFormat _swapChainImageFormat;
VkExtent2D _swapChainExtent;
std::vector<FrameBuffer> _framebuffers;
std::vector<ImageView> _imageViews;
VkSwapchainKHR _swapChain;
VkFormat _swapChainImageFormat;
VkExtent2D _swapChainExtent;
class Renderer* _renderer = nullptr;
};
}