mirror of
https://github.com/seekrs/MacroLibX.git
synced 2026-01-11 14:43:34 +00:00
fixing compatibility, workign on renderer
This commit is contained in:
8
Makefile
8
Makefile
@@ -6,15 +6,15 @@
|
|||||||
# By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ #
|
# By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2022/10/04 16:43:41 by maldavid #+# #+# #
|
# Created: 2022/10/04 16:43:41 by maldavid #+# #+# #
|
||||||
# Updated: 2022/10/05 19:25:51 by maldavid ### ########.fr #
|
# Updated: 2022/12/18 01:57:53 by maldavid ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
NAME = libMicroX.so
|
NAME = libmlx.so
|
||||||
|
|
||||||
SRCS = $(wildcard $(addsuffix /*.cpp, ./src/core))
|
SRCS = $(wildcard $(addsuffix /*.cpp, ./src/core))
|
||||||
SRCS += $(wildcard $(addsuffix /*.cpp, ./src/platform))
|
SRCS += $(wildcard $(addsuffix /*.cpp, ./src/platform))
|
||||||
SRCS += $(wildcard $(addsuffix /*.cpp, ./src/renderer))
|
SRCS += $(wildcard $(addsuffix /*.cpp, ./src/renderer/**))
|
||||||
|
|
||||||
OBJS = $(SRCS:.cpp=.o)
|
OBJS = $(SRCS:.cpp=.o)
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ DEBUG ?= false
|
|||||||
|
|
||||||
CXX = g++
|
CXX = g++
|
||||||
CXXFLAGS = -std=c++17 -O3 -fPIC
|
CXXFLAGS = -std=c++17 -O3 -fPIC
|
||||||
INCLUDES = -I./includes -I./src
|
INCLUDES = -I./includes -I./src -I./third_party
|
||||||
|
|
||||||
ifeq ($(DEBUG), true)
|
ifeq ($(DEBUG), true)
|
||||||
CXXFLAGS += -g
|
CXXFLAGS += -g
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -1,4 +1,4 @@
|
|||||||
# MicroLibX
|
# MacroLibX
|
||||||
|
|
||||||
A rewrite of School 42's MiniLibX using SDL2 and Vulkan. The goal of this version is to give a light, fast and modern graphical tool while keeping the same API as the version currently used at 42.
|
A rewrite of School 42's MiniLibX using SDL2 and Vulkan. The goal of this version is to give a light, fast and modern graphical tool while keeping the same API as the version currently used at 42.
|
||||||
|
|
||||||
@@ -19,10 +19,16 @@ For Arch based distros
|
|||||||
~ sudo pacman -S sdl2
|
~ sudo pacman -S sdl2
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Get MicroLibX
|
2. Get MacroLibX
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
~ git clone https://github.com/420verfl0w/MicroLibX.git
|
~ git clone https://github.com/420verfl0w/MacroLibX.git
|
||||||
~ cd MicroLibX
|
~ cd MacroLibX
|
||||||
~ make
|
~ make
|
||||||
```
|
```
|
||||||
|
|
||||||
|
3. Compile your project
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gcc myApp.c MacroLibX/libmlx.so -lSDL2
|
||||||
|
```
|
||||||
|
|||||||
@@ -6,26 +6,34 @@
|
|||||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2022/10/04 16:56:35 by maldavid #+# #+# */
|
/* Created: 2022/10/04 16:56:35 by maldavid #+# #+# */
|
||||||
/* Updated: 2022/10/05 18:42:22 by maldavid ### ########.fr */
|
/* Updated: 2022/12/18 04:03:37 by maldavid ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#ifndef __MICRO_LIB_X_H__
|
#ifndef __MACRO_LIB_X_H__
|
||||||
#define __MICRO_LIB_X_H__
|
#define __MACRO_LIB_X_H__
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void mlx_init();
|
void* mlx_init();
|
||||||
void mlx_new_window(int w, int h, const char* title);
|
void* mlx_new_window(void* mlx, int w, int h, const char* title);
|
||||||
int mlx_loop();
|
|
||||||
|
int mlx_loop_hook(void* mlx, int (*f)(void*), void* param);
|
||||||
|
int mlx_loop(void* mlx);
|
||||||
|
int mlx_loop_end(void* mlx);
|
||||||
|
|
||||||
int mlx_mouse_show();
|
int mlx_mouse_show();
|
||||||
int mlx_mouse_hide();
|
int mlx_mouse_hide();
|
||||||
int mlx_mouse_move(void* win_ptr, int x, int y);
|
int mlx_mouse_move(void* win_ptr, int x, int y);
|
||||||
int mlx_mouse_get_pos(void* win_ptr, int* x, int* y);
|
int mlx_mouse_get_pos(void* win_ptr, int* x, int* y);
|
||||||
|
|
||||||
|
int mlx_pixel_put(void* mlx, void* win_ptr, int x, int y, int color);
|
||||||
|
|
||||||
|
int mlx_destroy_window(void* mlx, void* win_ptr);
|
||||||
|
int mlx_destroy_display(void* mlx);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2022/10/04 22:10:52 by maldavid #+# #+# */
|
/* Created: 2022/10/04 22:10:52 by maldavid #+# #+# */
|
||||||
/* Updated: 2022/10/05 16:58:11 by maldavid ### ########.fr */
|
/* Updated: 2022/12/18 02:49:45 by maldavid ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@@ -19,6 +19,8 @@ namespace mlx::core
|
|||||||
while(_in.is_running())
|
while(_in.is_running())
|
||||||
{
|
{
|
||||||
_in.update();
|
_in.update();
|
||||||
|
if(_loop_hook)
|
||||||
|
_loop_hook(_param);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2022/10/04 21:49:46 by maldavid #+# #+# */
|
/* Created: 2022/10/04 21:49:46 by maldavid #+# #+# */
|
||||||
/* Updated: 2022/10/05 19:23:15 by maldavid ### ########.fr */
|
/* Updated: 2022/12/18 03:45:13 by maldavid ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
|
|
||||||
@@ -31,26 +32,32 @@ namespace mlx::core
|
|||||||
|
|
||||||
inline void* new_window(std::size_t w, std::size_t h, std::string title)
|
inline void* new_window(std::size_t w, std::size_t h, std::string title)
|
||||||
{
|
{
|
||||||
_wins.emplace_back(std::make_shared<Window>(w, h, std::move(title), _wins.size()));
|
_wins.emplace_back(std::make_shared<MLX_Window>(w, h, std::move(title), _wins.size()));
|
||||||
return reinterpret_cast<void*>(&_wins.back()->get_id());
|
return static_cast<void*>(&_wins.back()->get_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int get_mouse_pos(void* win_ptr, int* x, int* y) noexcept
|
inline int get_mouse_pos(void* win_ptr, int* x, int* y) noexcept
|
||||||
{
|
{
|
||||||
if(*reinterpret_cast<int*>(win_ptr) > _wins.size())
|
if(*static_cast<int*>(win_ptr) > _wins.size())
|
||||||
{
|
|
||||||
error::report(e_kind::error, "Invalid window pointer");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void loop_hook(int (*f)(void*), void* param) { _loop_hook = f; _param = param; }
|
||||||
|
inline void loop_end() noexcept { _in.finish(); }
|
||||||
|
|
||||||
|
inline void pixel_put(void* win_ptr, int x, int y, int color) const noexcept { _wins[*static_cast<int*>(win_ptr)]->pixel_put(x, y, color); }
|
||||||
|
|
||||||
|
inline void destroy_window(void* win_ptr) { _wins[*static_cast<int*>(win_ptr)].reset(); }
|
||||||
|
|
||||||
void run() noexcept;
|
void run() noexcept;
|
||||||
|
|
||||||
~Application() = default;
|
~Application() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Input _in;
|
Input _in;
|
||||||
std::vector<std::shared_ptr<Window>> _wins;
|
std::vector<std::shared_ptr<MLX_Window>> _wins;
|
||||||
|
std::function<int(void*)> _loop_hook;
|
||||||
|
void* _param = nullptr;
|
||||||
bool _is_loop_running = false;
|
bool _is_loop_running = false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2022/10/04 17:35:20 by maldavid #+# #+# */
|
/* Created: 2022/10/04 17:35:20 by maldavid #+# #+# */
|
||||||
/* Updated: 2022/10/05 18:45:52 by maldavid ### ########.fr */
|
/* Updated: 2022/12/18 03:42:18 by maldavid ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@@ -17,52 +17,67 @@
|
|||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
static std::unique_ptr<mlx::core::Application> __main_app = nullptr;
|
void* mlx_init()
|
||||||
|
|
||||||
void mlx_init()
|
|
||||||
{
|
{
|
||||||
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0)
|
return new mlx::core::Application();
|
||||||
mlx::core::error::report(e_kind::fatal_error, "Unable to init the SDL2");
|
|
||||||
__main_app.reset(new mlx::core::Application());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void* mlx_new_window(int w, int h, const char* title)
|
void* mlx_new_window(void* mlx, int w, int h, const char* title)
|
||||||
{
|
{
|
||||||
if(__main_app == nullptr)
|
return static_cast<mlx::core::Application*>(mlx)->new_window(w, h, title);
|
||||||
mlx::core::error::report(e_kind::fatal_error, "You must initialize the mlx before you can create new windows");
|
|
||||||
return __main_app->new_window(w, h, title);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int mlx_loop()
|
int mlx_loop_hook(void* mlx, int (*f)(void*), void* param)
|
||||||
{
|
{
|
||||||
if(__main_app == nullptr)
|
static_cast<mlx::core::Application*>(mlx)->loop_hook(f, param);
|
||||||
mlx::core::error::report(e_kind::fatal_error, "You must initialize the mlx before you can run the main loop");
|
return 0;
|
||||||
__main_app->run();
|
}
|
||||||
|
|
||||||
|
int mlx_loop(void* mlx)
|
||||||
|
{
|
||||||
|
static_cast<mlx::core::Application*>(mlx)->run();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mlx_loop_end(void* mlx)
|
||||||
|
{
|
||||||
|
static_cast<mlx::core::Application*>(mlx)->loop_end();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mlx_mouse_show()
|
int mlx_mouse_show()
|
||||||
{
|
{
|
||||||
if(__main_app == nullptr)
|
|
||||||
mlx::core::error::report(e_kind::fatal_error, "You must initialize the mlx before you can modify the cursor");
|
|
||||||
return SDL_ShowCursor(SDL_ENABLE);
|
return SDL_ShowCursor(SDL_ENABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mlx_mouse_hide()
|
int mlx_mouse_hide()
|
||||||
{
|
{
|
||||||
if(__main_app == nullptr)
|
|
||||||
mlx::core::error::report(e_kind::fatal_error, "You must initialize the mlx before you can modify the cursor");
|
|
||||||
return SDL_ShowCursor(SDL_DISABLE);
|
return SDL_ShowCursor(SDL_DISABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mlx_mouse_move(void* win_ptr, int x, int y)
|
int mlx_mouse_move(void* win_ptr, int x, int y)
|
||||||
{
|
{
|
||||||
if(__main_app == nullptr)
|
|
||||||
mlx::core::error::report(e_kind::fatal_error, "You must initialize the mlx before you can modify the mouse");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int mlx_mouse_get_pos(void* win_ptr, int* x, int* y)
|
int mlx_mouse_get_pos(void* win_ptr, int* x, int* y)
|
||||||
{
|
{
|
||||||
if(__main_app == nullptr)
|
}
|
||||||
mlx::core::error::report(e_kind::fatal_error, "You must initialize the mlx before you can access to the mouse");
|
|
||||||
|
int mlx_pixel_put(void* mlx, void* win_ptr, int x, int y, int color)
|
||||||
|
{
|
||||||
|
static_cast<mlx::core::Application*>(mlx)->pixel_put(win_ptr, x, y, color);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mlx_destroy_window(void* mlx, void* win_ptr)
|
||||||
|
{
|
||||||
|
static_cast<mlx::core::Application*>(mlx)->destroy_window(win_ptr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mlx_destroy_display(void* mlx)
|
||||||
|
{
|
||||||
|
delete static_cast<mlx::core::Application*>(mlx);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,26 +6,35 @@
|
|||||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2022/10/04 17:48:06 by maldavid #+# #+# */
|
/* Created: 2022/10/04 17:48:06 by maldavid #+# #+# */
|
||||||
/* Updated: 2022/10/04 21:18:35 by maldavid ### ########.fr */
|
/* Updated: 2022/12/17 23:28:22 by maldavid ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <cstdarg>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
|
|
||||||
namespace mlx::core::error
|
namespace mlx::core::error
|
||||||
{
|
{
|
||||||
void report(e_kind kind, std::string msg)
|
void report(e_kind kind, std::string msg, ...)
|
||||||
{
|
{
|
||||||
|
char buffer[1024];
|
||||||
|
|
||||||
|
va_list al;
|
||||||
|
va_start(al, msg);
|
||||||
|
std::vsprintf(buffer, std::move(msg).c_str(), al);
|
||||||
|
va_end(al);
|
||||||
|
|
||||||
switch(kind)
|
switch(kind)
|
||||||
{
|
{
|
||||||
case e_kind::message: std::cout << "[MicroLibX] Message : " << msg << std::endl; break;
|
case e_kind::message: std::cout << "[MicroLibX] Message : " << buffer << std::endl; break;
|
||||||
case e_kind::warning: std::cout << "[MicroLibX] Warning : " << msg << std::endl; break;
|
case e_kind::warning: std::cout << "[MicroLibX] Warning : " << buffer << std::endl; break;
|
||||||
case e_kind::error: std::cerr << "[MicroLibX] Error : " << msg << std::endl; break;
|
case e_kind::error: std::cerr << "[MicroLibX] Error : " << buffer << std::endl; break;
|
||||||
case e_kind::fatal_error:
|
case e_kind::fatal_error:
|
||||||
std::cerr << "[MicroLibX] Fatal Error : " << msg << std::endl;
|
std::cerr << "[MicroLibX] Fatal Error : " << buffer << std::endl;
|
||||||
std::exit(EXIT_SUCCESS);
|
std::exit(EXIT_SUCCESS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2022/10/04 17:42:32 by maldavid #+# #+# */
|
/* Created: 2022/10/04 17:42:32 by maldavid #+# #+# */
|
||||||
/* Updated: 2022/10/04 21:51:42 by maldavid ### ########.fr */
|
/* Updated: 2022/10/08 19:06:41 by maldavid ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ enum class e_kind
|
|||||||
|
|
||||||
namespace mlx::core::error
|
namespace mlx::core::error
|
||||||
{
|
{
|
||||||
void report(e_kind kind, std::string msg);
|
void report(e_kind kind, std::string msg, ...);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __MLX_ERRORS__
|
#endif // __MLX_ERRORS__
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2022/10/05 16:30:19 by maldavid #+# #+# */
|
/* Created: 2022/10/05 16:30:19 by maldavid #+# #+# */
|
||||||
/* Updated: 2022/10/05 19:24:30 by maldavid ### ########.fr */
|
/* Updated: 2022/12/18 01:13:32 by maldavid ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
namespace mlx
|
namespace mlx
|
||||||
{
|
{
|
||||||
Input::Input(const std::vector<std::shared_ptr<Window>>& wins) : _wins(wins)
|
Input::Input(const std::vector<std::shared_ptr<MLX_Window>>& wins) : _wins(wins)
|
||||||
{
|
{
|
||||||
std::memset(_keys.data(), 0, SDL_NUM_SCANCODES);
|
std::memset(_keys.data(), 0, SDL_NUM_SCANCODES);
|
||||||
std::memset(_mouse.data(), 0, 8);
|
std::memset(_mouse.data(), 0, 8);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2022/10/05 16:27:35 by maldavid #+# #+# */
|
/* Created: 2022/10/05 16:27:35 by maldavid #+# #+# */
|
||||||
/* Updated: 2022/10/05 19:53:18 by maldavid ### ########.fr */
|
/* Updated: 2022/12/18 01:13:19 by maldavid ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ namespace mlx
|
|||||||
class Input
|
class Input
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Input(const std::vector<std::shared_ptr<Window>>& wins);
|
Input(const std::vector<std::shared_ptr<MLX_Window>>& wins);
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ namespace mlx
|
|||||||
SDL_Event _event;
|
SDL_Event _event;
|
||||||
std::array<uint8_t, SDL_NUM_SCANCODES> _keys;
|
std::array<uint8_t, SDL_NUM_SCANCODES> _keys;
|
||||||
std::array<uint8_t, 8> _mouse;
|
std::array<uint8_t, 8> _mouse;
|
||||||
std::vector<std::shared_ptr<Window>> _wins;
|
std::vector<std::shared_ptr<MLX_Window>> _wins;
|
||||||
|
|
||||||
int _x = 0;
|
int _x = 0;
|
||||||
int _y = 0;
|
int _y = 0;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2022/10/04 17:36:44 by maldavid #+# #+# */
|
/* Created: 2022/10/04 17:36:44 by maldavid #+# #+# */
|
||||||
/* Updated: 2022/10/05 18:39:11 by maldavid ### ########.fr */
|
/* Updated: 2022/12/18 01:12:05 by maldavid ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@@ -15,14 +15,14 @@
|
|||||||
|
|
||||||
namespace mlx
|
namespace mlx
|
||||||
{
|
{
|
||||||
Window::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)
|
||||||
{
|
{
|
||||||
_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)
|
if(!_win)
|
||||||
core::error::report(e_kind::fatal_error, std::string("Unable to open a new window, ") + SDL_GetError());
|
core::error::report(e_kind::fatal_error, std::string("Unable to open a new window, ") + SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::~Window()
|
MLX_Window::~MLX_Window()
|
||||||
{
|
{
|
||||||
if(_win)
|
if(_win)
|
||||||
SDL_DestroyWindow(_win);
|
SDL_DestroyWindow(_win);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2022/10/04 21:53:12 by maldavid #+# #+# */
|
/* Created: 2022/10/04 21:53:12 by maldavid #+# #+# */
|
||||||
/* Updated: 2022/10/05 19:10:35 by maldavid ### ########.fr */
|
/* Updated: 2022/12/18 03:41:53 by maldavid ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@@ -18,14 +18,17 @@
|
|||||||
|
|
||||||
namespace mlx
|
namespace mlx
|
||||||
{
|
{
|
||||||
class Window
|
class MLX_Window
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Window(std::size_t w, std::size_t h, std::string title, int id);
|
MLX_Window(std::size_t w, std::size_t h, std::string title, int id);
|
||||||
|
|
||||||
inline int& get_id() noexcept { return _id; }
|
inline int& get_id() noexcept { return _id; }
|
||||||
|
inline SDL_Window* getNativeWindow() const noexcept { return _win; }
|
||||||
|
|
||||||
~Window();
|
void pixel_put(int x, int y, int color) {}
|
||||||
|
|
||||||
|
~MLX_Window();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SDL_Window* _win = nullptr;
|
SDL_Window* _win = nullptr;
|
||||||
|
|||||||
93
src/renderer/buffers/vk_buffer.cpp
git.filemode.normal_file
93
src/renderer/buffers/vk_buffer.cpp
git.filemode.normal_file
@@ -0,0 +1,93 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_buffer.cpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2022/10/08 18:55:57 by maldavid #+# #+# */
|
||||||
|
/* Updated: 2022/12/18 02:10:37 by maldavid ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "vk_buffer.h"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
void Buffer::create(Buffer::kind type, VkDeviceSize size, VkBufferUsageFlags usage, const void* data)
|
||||||
|
{
|
||||||
|
if(type == Buffer::kind::uniform)
|
||||||
|
{
|
||||||
|
_usage = usage;
|
||||||
|
_flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_usage = usage;
|
||||||
|
_flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
_size = size;
|
||||||
|
|
||||||
|
createBuffer(_usage, _flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Buffer::destroy() noexcept
|
||||||
|
{
|
||||||
|
vkDestroyBuffer(Render_Core::get().getDevice().get(), _buffer, nullptr);
|
||||||
|
vkFreeMemory(Render_Core::get().getDevice().get(), _memory, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties)
|
||||||
|
{
|
||||||
|
VkPhysicalDeviceMemoryProperties memProperties;
|
||||||
|
vkGetPhysicalDeviceMemoryProperties(Render_Core::get().getDevice().getPhysicalDevice(), &memProperties);
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < memProperties.memoryTypeCount; i++)
|
||||||
|
{
|
||||||
|
if((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
core::error::report(e_kind::fatal_error, "Vulkan : failed to find suitable memory type");
|
||||||
|
return -1; // just to avoid warning
|
||||||
|
}
|
||||||
|
|
||||||
|
void Buffer::createBuffer(VkBufferUsageFlags usage, VkMemoryPropertyFlags properties)
|
||||||
|
{
|
||||||
|
VkBufferCreateInfo bufferInfo{};
|
||||||
|
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||||
|
bufferInfo.size = _size;
|
||||||
|
bufferInfo.usage = usage;
|
||||||
|
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
|
||||||
|
auto device = Render_Core::get().getDevice().get();
|
||||||
|
|
||||||
|
if(vkCreateBuffer(device, &bufferInfo, nullptr, &_buffer) != VK_SUCCESS)
|
||||||
|
core::error::report(e_kind::fatal_error, "Vulkan : failed to create buffer");
|
||||||
|
|
||||||
|
VkMemoryRequirements memRequirements;
|
||||||
|
vkGetBufferMemoryRequirements(device, _buffer, &memRequirements);
|
||||||
|
|
||||||
|
VkMemoryAllocateInfo allocInfo{};
|
||||||
|
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
|
allocInfo.allocationSize = memRequirements.size;
|
||||||
|
allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, properties);
|
||||||
|
|
||||||
|
if(vkAllocateMemory(device, &allocInfo, nullptr, &_memory) != VK_SUCCESS)
|
||||||
|
core::error::report(e_kind::fatal_error, "Vulkan : failed to allocate buffer memory");
|
||||||
|
if(vkBindBufferMemory(device, _buffer, _memory, _offset) != VK_SUCCESS)
|
||||||
|
core::error::report(e_kind::fatal_error, "Vulkan : unable to bind device memory to a buffer object");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Buffer::flush(VkDeviceSize size, VkDeviceSize offset)
|
||||||
|
{
|
||||||
|
VkMappedMemoryRange mappedRange{};
|
||||||
|
mappedRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
|
||||||
|
mappedRange.memory = _memory;
|
||||||
|
mappedRange.offset = offset;
|
||||||
|
mappedRange.size = size;
|
||||||
|
vkFlushMappedMemoryRanges(Render_Core::get().getDevice().get(), 1, &mappedRange);
|
||||||
|
}
|
||||||
|
}
|
||||||
58
src/renderer/buffers/vk_buffer.h
git.filemode.normal_file
58
src/renderer/buffers/vk_buffer.h
git.filemode.normal_file
@@ -0,0 +1,58 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_buffer.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2022/10/06 23:18:52 by maldavid #+# #+# */
|
||||||
|
/* Updated: 2022/12/18 02:10:08 by maldavid ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef __MLX_VK_BUFFER__
|
||||||
|
#define __MLX_VK_BUFFER__
|
||||||
|
|
||||||
|
#include <volk.h>
|
||||||
|
#include <renderer/core/render_core.h>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
class Buffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class kind { dynamic, uniform };
|
||||||
|
|
||||||
|
void create(kind type, VkDeviceSize size, VkBufferUsageFlags usage, const void* data = nullptr);
|
||||||
|
void destroy() noexcept;
|
||||||
|
|
||||||
|
inline void mapMem(void** data = nullptr, VkDeviceSize size = VK_WHOLE_SIZE, VkDeviceSize offset = 0) noexcept
|
||||||
|
{
|
||||||
|
if(vkMapMemory(Render_Core::get().getDevice().get(), _memory, _offset + offset, size, 0, data) != VK_SUCCESS)
|
||||||
|
core::error::report(e_kind::fatal_error, "Vulkan : failed to map a buffer");
|
||||||
|
}
|
||||||
|
inline void unmapMem() noexcept { vkUnmapMemory(Render_Core::get().getDevice().get(), _memory); }
|
||||||
|
|
||||||
|
void flush(VkDeviceSize size = VK_WHOLE_SIZE, VkDeviceSize offset = 0);
|
||||||
|
|
||||||
|
inline unsigned int getSize() noexcept { return _size; }
|
||||||
|
inline unsigned int getOffset() noexcept { return _offset; }
|
||||||
|
inline VkDeviceMemory getDeviceMemory() noexcept { return _memory; }
|
||||||
|
inline VkBuffer& operator()() noexcept { return _buffer; }
|
||||||
|
inline VkBuffer& get() noexcept { return _buffer; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
VkDeviceMemory _memory = VK_NULL_HANDLE;
|
||||||
|
VkDeviceSize _offset = 0;
|
||||||
|
VkDeviceSize _size = 0;
|
||||||
|
VkBuffer _buffer = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void createBuffer(VkBufferUsageFlags usage, VkMemoryPropertyFlags properties);
|
||||||
|
|
||||||
|
VkBufferUsageFlags _usage = 0;
|
||||||
|
VkMemoryPropertyFlags _flags = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
34
src/renderer/buffers/vk_ubo.cpp
git.filemode.normal_file
34
src/renderer/buffers/vk_ubo.cpp
git.filemode.normal_file
@@ -0,0 +1,34 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_ubo.cpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2022/10/06 18:45:52 by maldavid #+# #+# */
|
||||||
|
/* Updated: 2022/12/18 00:25:55 by maldavid ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "vk_ubo.h"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
void UBO::setData(uint32_t size, const void* data)
|
||||||
|
{
|
||||||
|
void* temp = nullptr;
|
||||||
|
mapMem(&temp);
|
||||||
|
std::memcpy(temp, data, static_cast<size_t>(size));
|
||||||
|
unmapMem();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UBO::setDynamicData(uint32_t size, uint32_t typeSize, const void* data)
|
||||||
|
{
|
||||||
|
void* temp = nullptr;
|
||||||
|
mapMem(&temp);
|
||||||
|
std::memcpy(temp, data, static_cast<size_t>(size));
|
||||||
|
Buffer::flush();
|
||||||
|
unmapMem();
|
||||||
|
}
|
||||||
|
}
|
||||||
30
src/renderer/buffers/vk_ubo.h
git.filemode.normal_file
30
src/renderer/buffers/vk_ubo.h
git.filemode.normal_file
@@ -0,0 +1,30 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_ubo.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2022/10/06 18:45:29 by maldavid #+# #+# */
|
||||||
|
/* Updated: 2022/10/06 18:45:49 by maldavid ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef __MLX_VK_UBO__
|
||||||
|
#define __MLX_VK_UBO__
|
||||||
|
|
||||||
|
#include "vk_buffer.h"
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
class UBO : public Buffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline void create(uint32_t size) { Buffer::create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); }
|
||||||
|
|
||||||
|
void setData(uint32_t size, const void* data);
|
||||||
|
void setDynamicData(uint32_t size, uint32_t typeSize, const void* data);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __MLX_VK_UBO__
|
||||||
49
src/renderer/buffers/vk_vbo.cpp
git.filemode.normal_file
49
src/renderer/buffers/vk_vbo.cpp
git.filemode.normal_file
@@ -0,0 +1,49 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_vbo.cpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2022/10/06 18:28:08 by maldavid #+# #+# */
|
||||||
|
/* Updated: 2022/12/18 00:28:52 by maldavid ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "vk_vbo.h"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
void VBO::setData(uint32_t size, const void* data)
|
||||||
|
{
|
||||||
|
if(size > _size)
|
||||||
|
core::error::report(e_kind::error, "Vulkan : trying to store to much data in a vertex buffer (%d on %d)", size, _size);
|
||||||
|
|
||||||
|
if(data == nullptr)
|
||||||
|
core::error::report(e_kind::warning, "Vulkan : mapping null data in a vertex buffer");
|
||||||
|
|
||||||
|
void* temp = nullptr;
|
||||||
|
mapMem(&temp);
|
||||||
|
std::memcpy(temp, data, static_cast<size_t>(size));
|
||||||
|
unmapMem();
|
||||||
|
|
||||||
|
_used_size += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VBO::setSubData(uint32_t offset, uint32_t size, const void* data)
|
||||||
|
{
|
||||||
|
if(size + _used_size > _size)
|
||||||
|
core::error::report(e_kind::error, "Vulkan : trying to store to much data in a vertex buffer (%d on %d)", size + _used_size, _size);
|
||||||
|
|
||||||
|
if(data == nullptr)
|
||||||
|
core::error::report(e_kind::warning, "Vulkan : mapping null data in a vertex buffer");
|
||||||
|
|
||||||
|
void* temp = nullptr;
|
||||||
|
mapMem(&temp, size, offset);
|
||||||
|
std::memcpy(temp, data, static_cast<size_t>(size));
|
||||||
|
unmapMem();
|
||||||
|
|
||||||
|
_used_size += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
35
src/renderer/buffers/vk_vbo.h
git.filemode.normal_file
35
src/renderer/buffers/vk_vbo.h
git.filemode.normal_file
@@ -0,0 +1,35 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_vbo.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef __MLX_VK_VBO__
|
||||||
|
#define __MLX_VK_VBO__
|
||||||
|
|
||||||
|
#include "vk_buffer.h"
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
class VBO : public Buffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline void create(uint32_t size) { Buffer::create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); }
|
||||||
|
|
||||||
|
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); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t _used_size = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __MLX_VK_VBO__
|
||||||
58
src/renderer/command/vk_cmd_buffer.cpp
git.filemode.normal_file
58
src/renderer/command/vk_cmd_buffer.cpp
git.filemode.normal_file
@@ -0,0 +1,58 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_cmd_buffer.cpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "vk_cmd_buffer.h"
|
||||||
|
#include <renderer/core/render_core.h>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
void CmdBuffer::init()
|
||||||
|
{
|
||||||
|
VkCommandBufferAllocateInfo allocInfo{};
|
||||||
|
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||||
|
allocInfo.commandPool = Render_Core::get().getCmdPool().get();
|
||||||
|
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||||
|
allocInfo.commandBufferCount = 1;
|
||||||
|
|
||||||
|
if(vkAllocateCommandBuffers(Render_Core::get().getDevice().get(), &allocInfo, &_cmd_buffer) != VK_SUCCESS)
|
||||||
|
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)
|
||||||
|
return;
|
||||||
|
|
||||||
|
VkCommandBufferBeginInfo beginInfo{};
|
||||||
|
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
|
beginInfo.flags = usage;
|
||||||
|
if(vkBeginCommandBuffer(_cmd_buffer, &beginInfo) != VK_SUCCESS)
|
||||||
|
core::error::report(e_kind::fatal_error, "Vulkan : failed to begin recording command buffer");
|
||||||
|
|
||||||
|
_is_recording = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CmdBuffer::endRecord()
|
||||||
|
{
|
||||||
|
if(!_is_recording)
|
||||||
|
return;
|
||||||
|
if(vkEndCommandBuffer(_cmd_buffer) != VK_SUCCESS)
|
||||||
|
core::error::report(e_kind::fatal_error, "Vulkan : failed to end recording command buffer");
|
||||||
|
|
||||||
|
_is_recording = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
38
src/renderer/command/vk_cmd_buffer.h
git.filemode.normal_file
38
src/renderer/command/vk_cmd_buffer.h
git.filemode.normal_file
@@ -0,0 +1,38 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_cmd_buffer.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef __MLX_VK_CMD_BUFFER__
|
||||||
|
#define __MLX_VK_CMD_BUFFER__
|
||||||
|
|
||||||
|
#include <volk.h>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
class CmdBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void init();
|
||||||
|
void destroy() noexcept;
|
||||||
|
|
||||||
|
void beginRecord(VkCommandBufferUsageFlags usage = 0);
|
||||||
|
void endRecord();
|
||||||
|
|
||||||
|
inline VkCommandBuffer& operator()() noexcept { return _cmd_buffer; }
|
||||||
|
inline VkCommandBuffer& get() noexcept { return _cmd_buffer; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
VkCommandBuffer _cmd_buffer = VK_NULL_HANDLE;
|
||||||
|
bool _is_recording = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __MLX_VK_CMD_BUFFER__
|
||||||
33
src/renderer/command/vk_cmd_pool.cpp
git.filemode.normal_file
33
src/renderer/command/vk_cmd_pool.cpp
git.filemode.normal_file
@@ -0,0 +1,33 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_cmd_pool.cpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "vk_cmd_pool.h"
|
||||||
|
#include <renderer/core/render_core.h>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
void CmdPool::init()
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CmdPool::destroy() noexcept
|
||||||
|
{
|
||||||
|
vkDestroyCommandPool(Render_Core::get().getDevice().get(), _cmd_pool, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
34
src/renderer/command/vk_cmd_pool.h
git.filemode.normal_file
34
src/renderer/command/vk_cmd_pool.h
git.filemode.normal_file
@@ -0,0 +1,34 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_cmd_pool.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2022/10/06 18:24:12 by maldavid #+# #+# */
|
||||||
|
/* Updated: 2022/12/18 01:08:31 by maldavid ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef __MLX_VK_CMD_POOL__
|
||||||
|
#define __MLX_VK_CMD_POOL__
|
||||||
|
|
||||||
|
#include <volk.h>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
class CmdPool
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void init();
|
||||||
|
void destroy() noexcept;
|
||||||
|
|
||||||
|
inline VkCommandPool& operator()() noexcept { return _cmd_pool; }
|
||||||
|
inline VkCommandPool& get() noexcept { return _cmd_pool; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
VkCommandPool _cmd_pool = VK_NULL_HANDLE;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __MLX_VK_CMD_POOL__
|
||||||
206
src/renderer/core/render_core.cpp
git.filemode.normal_file
206
src/renderer/core/render_core.cpp
git.filemode.normal_file
@@ -0,0 +1,206 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* render_core.cpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#define VOLK_IMPLEMENTATION
|
||||||
|
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
#define VK_USE_PLATFORM_WIN32_KHR
|
||||||
|
#elif defined(__APPLE__) || defined(__MACH__)
|
||||||
|
#define VK_USE_PLATFORM_MACOS_MVK
|
||||||
|
#else
|
||||||
|
#define VK_USE_PLATFORM_XLIB_KHR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "render_core.h"
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
namespace RCore
|
||||||
|
{
|
||||||
|
const char* verbaliseResultVk(VkResult result)
|
||||||
|
{
|
||||||
|
switch(result)
|
||||||
|
{
|
||||||
|
case VK_SUCCESS: return "Success";
|
||||||
|
case VK_NOT_READY: return "A fence or query has not yet completed";
|
||||||
|
case VK_TIMEOUT: return "A wait operation has not completed in the specified time";
|
||||||
|
case VK_EVENT_SET: return "An event is signaled";
|
||||||
|
case VK_EVENT_RESET: return "An event is unsignaled";
|
||||||
|
case VK_INCOMPLETE: return "A return array was too small for the result";
|
||||||
|
case VK_ERROR_OUT_OF_HOST_MEMORY: return "A host memory allocation has failed";
|
||||||
|
case VK_ERROR_OUT_OF_DEVICE_MEMORY: return "A device memory allocation has failed";
|
||||||
|
case VK_ERROR_INITIALIZATION_FAILED: return "Initialization of an object could not be completed for implementation-specific reasons";
|
||||||
|
case VK_ERROR_DEVICE_LOST: return "The logical or physical device has been lost";
|
||||||
|
case VK_ERROR_MEMORY_MAP_FAILED: return "Mapping of a memory object has failed";
|
||||||
|
case VK_ERROR_LAYER_NOT_PRESENT: return "A requested layer is not present or could not be loaded";
|
||||||
|
case VK_ERROR_EXTENSION_NOT_PRESENT: return "A requested extension is not supported";
|
||||||
|
case VK_ERROR_FEATURE_NOT_PRESENT: return "A requested feature is not supported";
|
||||||
|
case VK_ERROR_INCOMPATIBLE_DRIVER: return "The requested version of Vulkan is not supported by the driver or is otherwise incompatible";
|
||||||
|
case VK_ERROR_TOO_MANY_OBJECTS: return "Too many objects of the type have already been created";
|
||||||
|
case VK_ERROR_FORMAT_NOT_SUPPORTED: return "A requested format is not supported on this device";
|
||||||
|
case VK_ERROR_SURFACE_LOST_KHR: return "A surface is no longer available";
|
||||||
|
case VK_SUBOPTIMAL_KHR: return "A swapchain no longer matches the surface properties exactly, but can still be used";
|
||||||
|
case VK_ERROR_OUT_OF_DATE_KHR: return "A surface has changed in such a way that it is no longer compatible with the swapchain";
|
||||||
|
case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: return "The display used by a swapchain does not use the same presentable image layout";
|
||||||
|
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: return "The requested window is already connected to a VkSurfaceKHR, or to some other non-Vulkan API";
|
||||||
|
case VK_ERROR_VALIDATION_FAILED_EXT: return "A validation layer found an error";
|
||||||
|
|
||||||
|
default: return "Unknown Vulkan error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkVk(VkResult result)
|
||||||
|
{
|
||||||
|
if(result != 0)
|
||||||
|
core::error::report(result < 0 ? e_kind::fatal_error : e_kind::error, "Vulkan error : %s", verbaliseResultVk(result));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Render_Core::Render_Core() : _device(), _queues(), _surface(),
|
||||||
|
_cmd_pool(), _swapchain(), _instance()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void Render_Core::init()
|
||||||
|
{
|
||||||
|
_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;
|
||||||
|
std::unique_lock<std::mutex> watchdog(mutex, std::try_to_lock);
|
||||||
|
|
||||||
|
if(!_is_init)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vkDeviceWaitIdle(_device());
|
||||||
|
|
||||||
|
_swapchain.destroyFB();
|
||||||
|
_pass.destroy();
|
||||||
|
_swapchain.destroy();
|
||||||
|
_semaphore.destroy();
|
||||||
|
_cmd_pool.destroy();
|
||||||
|
_device.destroy();
|
||||||
|
_surface.destroy();
|
||||||
|
_instance.destroy();
|
||||||
|
|
||||||
|
_is_init = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
95
src/renderer/core/render_core.h
git.filemode.normal_file
95
src/renderer/core/render_core.h
git.filemode.normal_file
@@ -0,0 +1,95 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* render_core.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef __MLX_RENDER_CORE__
|
||||||
|
#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>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
namespace RCore
|
||||||
|
{
|
||||||
|
void checkVk(VkResult result);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr const int MAX_FRAMES_IN_FLIGHT = 2;
|
||||||
|
|
||||||
|
class Render_Core : public Singleton<Render_Core>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Render_Core();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
|
void destroyCommandBuffers();
|
||||||
|
void destroy();
|
||||||
|
|
||||||
|
bool beginFrame();
|
||||||
|
void endFrame();
|
||||||
|
|
||||||
|
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; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Device _device;
|
||||||
|
Queues _queues;
|
||||||
|
Surface _surface;
|
||||||
|
RenderPass _pass;
|
||||||
|
CmdPool _cmd_pool;
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __MLX_RENDER_CORE__
|
||||||
117
src/renderer/core/vk_device.cpp
git.filemode.normal_file
117
src/renderer/core/vk_device.cpp
git.filemode.normal_file
@@ -0,0 +1,117 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_device.cpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "render_core.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
const std::vector<const char*> deviceExtensions = {VK_KHR_SWAPCHAIN_EXTENSION_NAME};
|
||||||
|
|
||||||
|
void Device::init()
|
||||||
|
{
|
||||||
|
pickPhysicalDevice();
|
||||||
|
|
||||||
|
Queues::QueueFamilyIndices indices = Render_Core::get().getQueue().findQueueFamilies(_physicalDevice);
|
||||||
|
|
||||||
|
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
|
||||||
|
std::set<uint32_t> uniqueQueueFamilies = { indices.graphicsFamily.value(), indices.presentFamily.value() };
|
||||||
|
|
||||||
|
float queuePriority = 1.0f;
|
||||||
|
for(uint32_t queueFamily : uniqueQueueFamilies)
|
||||||
|
{
|
||||||
|
VkDeviceQueueCreateInfo queueCreateInfo{};
|
||||||
|
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||||
|
queueCreateInfo.queueFamilyIndex = queueFamily;
|
||||||
|
queueCreateInfo.queueCount = 1;
|
||||||
|
queueCreateInfo.pQueuePriorities = &queuePriority;
|
||||||
|
queueCreateInfos.push_back(queueCreateInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkPhysicalDeviceFeatures deviceFeatures{};
|
||||||
|
|
||||||
|
VkDeviceCreateInfo createInfo{};
|
||||||
|
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||||
|
|
||||||
|
createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
|
||||||
|
createInfo.pQueueCreateInfos = queueCreateInfos.data();
|
||||||
|
|
||||||
|
createInfo.pEnabledFeatures = &deviceFeatures;
|
||||||
|
|
||||||
|
createInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
|
||||||
|
createInfo.ppEnabledExtensionNames = deviceExtensions.data();
|
||||||
|
createInfo.enabledLayerCount = 0;
|
||||||
|
|
||||||
|
if(vkCreateDevice(_physicalDevice, &createInfo, nullptr, &_device) != VK_SUCCESS)
|
||||||
|
core::error::report(e_kind::fatal_error, "Vulkan : failed to create logcal device");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Device::pickPhysicalDevice()
|
||||||
|
{
|
||||||
|
uint32_t deviceCount = 0;
|
||||||
|
vkEnumeratePhysicalDevices(Render_Core::get().getInstance().get(), &deviceCount, nullptr);
|
||||||
|
|
||||||
|
if(deviceCount == 0)
|
||||||
|
core::error::report(e_kind::fatal_error, "Vulkan : failed to find GPUs with Vulkan support");
|
||||||
|
|
||||||
|
std::vector<VkPhysicalDevice> devices(deviceCount);
|
||||||
|
vkEnumeratePhysicalDevices(Render_Core::get().getInstance().get(), &deviceCount, devices.data());
|
||||||
|
|
||||||
|
for(const auto& device : devices)
|
||||||
|
{
|
||||||
|
if(isDeviceSuitable(device))
|
||||||
|
{
|
||||||
|
_physicalDevice = device;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_physicalDevice == VK_NULL_HANDLE)
|
||||||
|
core::error::report(e_kind::fatal_error, "Vulkan : failed to find a suitable GPU");
|
||||||
|
}
|
||||||
|
bool Device::isDeviceSuitable(VkPhysicalDevice device)
|
||||||
|
{
|
||||||
|
Queues::QueueFamilyIndices indices = Render_Core::get().getQueue().findQueueFamilies(device);
|
||||||
|
|
||||||
|
bool extensionsSupported = checkDeviceExtensionSupport(device);
|
||||||
|
|
||||||
|
bool swapChainAdequate = false;
|
||||||
|
if(extensionsSupported)
|
||||||
|
{
|
||||||
|
SwapChain::SwapChainSupportDetails swapChainSupport = Render_Core::get().getSwapChain().querySwapChainSupport(device);
|
||||||
|
swapChainAdequate = !swapChainSupport.formats.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
return indices.isComplete() && extensionsSupported && swapChainAdequate;
|
||||||
|
}
|
||||||
|
bool Device::checkDeviceExtensionSupport(VkPhysicalDevice device)
|
||||||
|
{
|
||||||
|
uint32_t extensionCount;
|
||||||
|
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr);
|
||||||
|
|
||||||
|
std::vector<VkExtensionProperties> availableExtensions(extensionCount);
|
||||||
|
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data());
|
||||||
|
|
||||||
|
std::set<std::string> requiredExtensions(deviceExtensions.begin(), deviceExtensions.end());
|
||||||
|
|
||||||
|
for(const auto& extension : availableExtensions)
|
||||||
|
requiredExtensions.erase(extension.extensionName);
|
||||||
|
|
||||||
|
return requiredExtensions.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Device::destroy() noexcept
|
||||||
|
{
|
||||||
|
vkDestroyDevice(_device, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
41
src/renderer/core/vk_device.h
git.filemode.normal_file
41
src/renderer/core/vk_device.h
git.filemode.normal_file
@@ -0,0 +1,41 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_device.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef __MLX_VK_DEVICE__
|
||||||
|
#define __MLX_VK_DEVICE__
|
||||||
|
|
||||||
|
#include <volk.h>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
class Device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void init();
|
||||||
|
void destroy() noexcept;
|
||||||
|
|
||||||
|
inline VkDevice& operator()() noexcept { return _device; }
|
||||||
|
inline VkDevice& get() noexcept { return _device; }
|
||||||
|
|
||||||
|
inline VkPhysicalDevice& getPhysicalDevice() noexcept { return _physicalDevice; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void pickPhysicalDevice();
|
||||||
|
bool isDeviceSuitable(VkPhysicalDevice device);
|
||||||
|
bool checkDeviceExtensionSupport(VkPhysicalDevice device);
|
||||||
|
|
||||||
|
VkPhysicalDevice _physicalDevice = VK_NULL_HANDLE;
|
||||||
|
VkDevice _device = VK_NULL_HANDLE;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __MLX_VK_DEVICE__
|
||||||
68
src/renderer/core/vk_instance.cpp
git.filemode.normal_file
68
src/renderer/core/vk_instance.cpp
git.filemode.normal_file
@@ -0,0 +1,68 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_instance.cpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "vk_instance.h"
|
||||||
|
#include "render_core.h"
|
||||||
|
#include <platform/window.h>
|
||||||
|
#include <SDL2/SDL_vulkan.h>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
namespace RCore { const char* verbaliseResultVk(VkResult result); }
|
||||||
|
|
||||||
|
void Instance::init()
|
||||||
|
{
|
||||||
|
VkApplicationInfo appInfo{};
|
||||||
|
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||||
|
appInfo.pApplicationName = "MicroLibX";
|
||||||
|
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
|
||||||
|
appInfo.pEngineName = "MicroLibX";
|
||||||
|
appInfo.engineVersion = VK_MAKE_VERSION(0, 0, 1);
|
||||||
|
appInfo.apiVersion = VK_API_VERSION_1_2;
|
||||||
|
|
||||||
|
VkInstanceCreateInfo createInfo{};
|
||||||
|
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||||
|
createInfo.pApplicationInfo = &appInfo;
|
||||||
|
|
||||||
|
auto extensions = getRequiredExtensions();
|
||||||
|
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
|
||||||
|
createInfo.ppEnabledExtensionNames = extensions.data();
|
||||||
|
|
||||||
|
VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo;
|
||||||
|
createInfo.enabledLayerCount = 0;
|
||||||
|
createInfo.pNext = nullptr;
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<const char*> Instance::getRequiredExtensions()
|
||||||
|
{
|
||||||
|
unsigned int count = 0;
|
||||||
|
if(!SDL_Vulkan_GetInstanceExtensions(Render_Core::get().getWindow()->getNativeWindow(), &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))
|
||||||
|
core::error::report(e_kind::error, "Vulkan : cannot get instance extentions from window : %s", SDL_GetError());
|
||||||
|
return extensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Instance::destroy() noexcept
|
||||||
|
{
|
||||||
|
vkDestroyInstance(_instance, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
37
src/renderer/core/vk_instance.h
git.filemode.normal_file
37
src/renderer/core/vk_instance.h
git.filemode.normal_file
@@ -0,0 +1,37 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_instance.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef __MLX_VK_INSTANCE__
|
||||||
|
#define __MLX_VK_INSTANCE__
|
||||||
|
|
||||||
|
#include <volk.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
class Instance
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void destroy() noexcept;
|
||||||
|
|
||||||
|
inline VkInstance& operator()() noexcept { return _instance; }
|
||||||
|
inline VkInstance& get() noexcept { return _instance; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<const char*> getRequiredExtensions();
|
||||||
|
VkInstance _instance = VK_NULL_HANDLE;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __MLX_VK_INSTANCE__
|
||||||
53
src/renderer/core/vk_queues.cpp
git.filemode.normal_file
53
src/renderer/core/vk_queues.cpp
git.filemode.normal_file
@@ -0,0 +1,53 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_queues.cpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "render_core.h"
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
Queues::QueueFamilyIndices Queues::findQueueFamilies(VkPhysicalDevice device)
|
||||||
|
{
|
||||||
|
uint32_t queueFamilyCount = 0;
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);
|
||||||
|
|
||||||
|
std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());
|
||||||
|
|
||||||
|
_families = Queues::QueueFamilyIndices{};
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for(const auto& queueFamily : queueFamilies)
|
||||||
|
{
|
||||||
|
if(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
||||||
|
_families->graphicsFamily = i;
|
||||||
|
|
||||||
|
VkBool32 presentSupport = false;
|
||||||
|
vkGetPhysicalDeviceSurfaceSupportKHR(device, i, Render_Core::get().getSurface().get(), &presentSupport);
|
||||||
|
|
||||||
|
if(presentSupport)
|
||||||
|
_families->presentFamily = i;
|
||||||
|
|
||||||
|
if(_families->isComplete())
|
||||||
|
break;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return *_families;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Queues::init()
|
||||||
|
{
|
||||||
|
if(!_families.has_value())
|
||||||
|
findQueueFamilies(Render_Core::get().getDevice().getPhysicalDevice());
|
||||||
|
vkGetDeviceQueue(Render_Core::get().getDevice().get(), _families->graphicsFamily.value(), 0, &_graphicsQueue);
|
||||||
|
vkGetDeviceQueue(Render_Core::get().getDevice().get(), _families->presentFamily.value(), 0, &_presentQueue);
|
||||||
|
}
|
||||||
|
}
|
||||||
48
src/renderer/core/vk_queues.h
git.filemode.normal_file
48
src/renderer/core/vk_queues.h
git.filemode.normal_file
@@ -0,0 +1,48 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_queues.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef __MLX_VK_QUEUES__
|
||||||
|
#define __MLX_VK_QUEUES__
|
||||||
|
|
||||||
|
#include <volk.h>
|
||||||
|
#include <optional>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
class Queues
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct QueueFamilyIndices
|
||||||
|
{
|
||||||
|
std::optional<uint32_t> graphicsFamily;
|
||||||
|
std::optional<uint32_t> presentFamily;
|
||||||
|
|
||||||
|
inline bool isComplete() { return graphicsFamily.has_value() && presentFamily.has_value(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device);
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
|
inline VkQueue& getGraphic() noexcept { return _graphicsQueue; }
|
||||||
|
inline VkQueue& getPresent() noexcept { return _presentQueue; }
|
||||||
|
inline QueueFamilyIndices getFamilies() noexcept { return *_families; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
VkQueue _graphicsQueue;
|
||||||
|
VkQueue _presentQueue;
|
||||||
|
std::optional<QueueFamilyIndices> _families;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __MLX_VK_QUEUES__
|
||||||
50
src/renderer/core/vk_semaphore.cpp
git.filemode.normal_file
50
src/renderer/core/vk_semaphore.cpp
git.filemode.normal_file
@@ -0,0 +1,50 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_semaphore.cpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "vk_semaphore.h"
|
||||||
|
#include "render_core.h"
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
void Semaphore::init()
|
||||||
|
{
|
||||||
|
_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);
|
||||||
|
|
||||||
|
VkSemaphoreCreateInfo semaphoreInfo{};
|
||||||
|
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||||
|
|
||||||
|
VkFenceCreateInfo fenceInfo{};
|
||||||
|
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||||
|
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||||
|
|
||||||
|
for(size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
||||||
|
{
|
||||||
|
if(vkCreateSemaphore(Render_Core::get().getDevice().get(), &semaphoreInfo, nullptr, &_imageAvailableSemaphores[i]) != VK_SUCCESS ||
|
||||||
|
vkCreateSemaphore(Render_Core::get().getDevice().get(), &semaphoreInfo, nullptr, &_renderFinishedSemaphores[i]) != VK_SUCCESS ||
|
||||||
|
vkCreateFence(Render_Core::get().getDevice().get(), &fenceInfo, nullptr, &_inFlightFences[i]) != VK_SUCCESS)
|
||||||
|
core::error::report(e_kind::fatal_error, "Vulkan : failed to create synchronization objects for a frame");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Semaphore::destroy() noexcept
|
||||||
|
{
|
||||||
|
for(size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
||||||
|
{
|
||||||
|
vkDestroySemaphore(Render_Core::get().getDevice().get(), _renderFinishedSemaphores[i], nullptr);
|
||||||
|
vkDestroySemaphore(Render_Core::get().getDevice().get(), _imageAvailableSemaphores[i], nullptr);
|
||||||
|
vkDestroyFence(Render_Core::get().getDevice().get(), _inFlightFences[i], nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
40
src/renderer/core/vk_semaphore.h
git.filemode.normal_file
40
src/renderer/core/vk_semaphore.h
git.filemode.normal_file
@@ -0,0 +1,40 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_semaphore.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef __MLX_VK_SEMAPHORE__
|
||||||
|
#define __MLX_VK_SEMAPHORE__
|
||||||
|
|
||||||
|
#include <volk.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
class Semaphore
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void init();
|
||||||
|
void destroy() noexcept;
|
||||||
|
|
||||||
|
inline VkSemaphore& getImageSemaphore(int i) noexcept { return _imageAvailableSemaphores[i]; }
|
||||||
|
inline VkSemaphore& getRenderImageSemaphore(int i) noexcept { return _renderFinishedSemaphores[i]; }
|
||||||
|
inline VkFence& getInFlightFence(int i) noexcept { return _inFlightFences[i]; }
|
||||||
|
inline VkFence& getInFlightImage(int i) noexcept { return _imagesInFlight[i]; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<VkSemaphore> _imageAvailableSemaphores;
|
||||||
|
std::vector<VkSemaphore> _renderFinishedSemaphores;
|
||||||
|
std::vector<VkFence> _inFlightFences;
|
||||||
|
std::vector<VkFence> _imagesInFlight;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __MLX_VK_SEMAPHORE__
|
||||||
40
src/renderer/core/vk_surface.cpp
git.filemode.normal_file
40
src/renderer/core/vk_surface.cpp
git.filemode.normal_file
@@ -0,0 +1,40 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_surface.cpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "render_core.h"
|
||||||
|
#include <platform/window.h>
|
||||||
|
#include <SDL2/SDL_vulkan.h>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
void Surface::create()
|
||||||
|
{
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
VkSurfaceFormatKHR Surface::chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats)
|
||||||
|
{
|
||||||
|
for(const auto& availableFormat : availableFormats)
|
||||||
|
{
|
||||||
|
if(availableFormat.format == VK_FORMAT_R8G8B8A8_SRGB && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
|
||||||
|
return availableFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
return availableFormats[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Surface::destroy() noexcept
|
||||||
|
{
|
||||||
|
vkDestroySurfaceKHR(Render_Core::get().getInstance().get(), _surface, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
37
src/renderer/core/vk_surface.h
git.filemode.normal_file
37
src/renderer/core/vk_surface.h
git.filemode.normal_file
@@ -0,0 +1,37 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_surface.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef __MLX_VK_SURFACE__
|
||||||
|
#define __MLX_VK_SURFACE__
|
||||||
|
|
||||||
|
#include <volk.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
class Surface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void create();
|
||||||
|
void destroy() noexcept;
|
||||||
|
|
||||||
|
VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats);
|
||||||
|
|
||||||
|
inline VkSurfaceKHR& operator()() noexcept { return _surface; }
|
||||||
|
inline VkSurfaceKHR& get() noexcept { return _surface; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
VkSurfaceKHR _surface = VK_NULL_HANDLE;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __MLX_VK_SURFACE__
|
||||||
39
src/renderer/swapchain/vk_framebuffer.cpp
git.filemode.normal_file
39
src/renderer/swapchain/vk_framebuffer.cpp
git.filemode.normal_file
@@ -0,0 +1,39 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_framebuffer.cpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include <volk.h>
|
||||||
|
#include <renderer/core/render_core.h>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
void FrameBuffer::init(SwapChain* swapchain, ImageView& image)
|
||||||
|
{
|
||||||
|
VkImageView attachments[] = { image() };
|
||||||
|
|
||||||
|
VkFramebufferCreateInfo framebufferInfo{};
|
||||||
|
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||||
|
framebufferInfo.renderPass = Render_Core::get().getRenderPass().get();
|
||||||
|
framebufferInfo.attachmentCount = 1;
|
||||||
|
framebufferInfo.pAttachments = attachments;
|
||||||
|
framebufferInfo.width = swapchain->_swapChainExtent.width;
|
||||||
|
framebufferInfo.height = swapchain->_swapChainExtent.height;
|
||||||
|
framebufferInfo.layers = 1;
|
||||||
|
|
||||||
|
if(vkCreateFramebuffer(Render_Core::get().getDevice().get(), &framebufferInfo, nullptr, &_framebuffer) != VK_SUCCESS)
|
||||||
|
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a framebuffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
void FrameBuffer::destroy() noexcept
|
||||||
|
{
|
||||||
|
vkDestroyFramebuffer(Render_Core::get().getDevice().get(), _framebuffer, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
34
src/renderer/swapchain/vk_framebuffer.h
git.filemode.normal_file
34
src/renderer/swapchain/vk_framebuffer.h
git.filemode.normal_file
@@ -0,0 +1,34 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_framebuffer.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef __MLX_VK_FRAMEBUFFER__
|
||||||
|
#define __MLX_VK_FRAMEBUFFER__
|
||||||
|
|
||||||
|
#include <volk.h>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
class FrameBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void init(class SwapChain* swapchain, class ImageView& image);
|
||||||
|
void destroy() noexcept;
|
||||||
|
|
||||||
|
inline VkFramebuffer& operator()() noexcept { return _framebuffer; }
|
||||||
|
inline VkFramebuffer& get() noexcept { return _framebuffer; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
VkFramebuffer _framebuffer = VK_NULL_HANDLE;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __MLX_VK_FRAMEBUFFER__
|
||||||
44
src/renderer/swapchain/vk_imageview.cpp
git.filemode.normal_file
44
src/renderer/swapchain/vk_imageview.cpp
git.filemode.normal_file
@@ -0,0 +1,44 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_imageview.cpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "vk_swapchain.h"
|
||||||
|
#include "vk_imageview.h"
|
||||||
|
#include <renderer/core/render_core.h>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
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.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
|
||||||
|
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
createInfo.subresourceRange.baseMipLevel = 0;
|
||||||
|
createInfo.subresourceRange.levelCount = 1;
|
||||||
|
createInfo.subresourceRange.baseArrayLayer = 0;
|
||||||
|
createInfo.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
|
if(vkCreateImageView(Render_Core::get().getDevice().get(), &createInfo, nullptr, &_image) != VK_SUCCESS)
|
||||||
|
core::error::report(e_kind::fatal_error, "Vulkan : failed to create an image view");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageView::destroy() noexcept
|
||||||
|
{
|
||||||
|
vkDestroyImageView(Render_Core::get().getDevice().get(), _image, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
34
src/renderer/swapchain/vk_imageview.h
git.filemode.normal_file
34
src/renderer/swapchain/vk_imageview.h
git.filemode.normal_file
@@ -0,0 +1,34 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_imageview.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef __MLX_VK_IMAGE_VIEW__
|
||||||
|
#define __MLX_VK_IMAGE_VIEW__
|
||||||
|
|
||||||
|
#include <volk.h>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
class ImageView
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void init(class SwapChain* swapchain, VkImage& image);
|
||||||
|
void destroy() noexcept;
|
||||||
|
|
||||||
|
inline VkImageView& operator()() noexcept { return _image; }
|
||||||
|
inline VkImageView& get() noexcept { return _image; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
VkImageView _image = VK_NULL_HANDLE;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __MLX_VK_IMAGE_VIEW__
|
||||||
84
src/renderer/swapchain/vk_render_pass.cpp
git.filemode.normal_file
84
src/renderer/swapchain/vk_render_pass.cpp
git.filemode.normal_file
@@ -0,0 +1,84 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_render_pass.cpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "vk_render_pass.h"
|
||||||
|
#include <renderer/core/render_core.h>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
void RenderPass::init()
|
||||||
|
{
|
||||||
|
VkAttachmentDescription colorAttachment{};
|
||||||
|
colorAttachment.format = Render_Core::get().getSwapChain()._swapChainImageFormat;
|
||||||
|
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
|
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
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;
|
||||||
|
|
||||||
|
VkAttachmentReference colorAttachmentRef{};
|
||||||
|
colorAttachmentRef.attachment = 0;
|
||||||
|
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
VkSubpassDescription subpass{};
|
||||||
|
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||||
|
subpass.colorAttachmentCount = 1;
|
||||||
|
subpass.pColorAttachments = &colorAttachmentRef;
|
||||||
|
|
||||||
|
VkRenderPassCreateInfo renderPassInfo{};
|
||||||
|
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||||
|
renderPassInfo.attachmentCount = 1;
|
||||||
|
renderPassInfo.pAttachments = &colorAttachment;
|
||||||
|
renderPassInfo.subpassCount = 1;
|
||||||
|
renderPassInfo.pSubpasses = &subpass;
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderPass::begin()
|
||||||
|
{
|
||||||
|
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.renderArea.offset = { 0, 0 };
|
||||||
|
renderPassInfo.renderArea.extent = Render_Core::get().getSwapChain()._swapChainExtent;
|
||||||
|
renderPassInfo.clearValueCount = 1;
|
||||||
|
renderPassInfo.pClearValues = &clearColor;
|
||||||
|
|
||||||
|
vkCmdBeginRenderPass(Render_Core::get().getActiveCmdBuffer().get(), &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
|
|
||||||
|
_is_running = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderPass::end()
|
||||||
|
{
|
||||||
|
if(!_is_running)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vkCmdEndRenderPass(Render_Core::get().getActiveCmdBuffer().get());
|
||||||
|
_is_running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderPass::destroy() noexcept
|
||||||
|
{
|
||||||
|
vkDestroyRenderPass(Render_Core::get().getDevice().get(), _renderPass, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
38
src/renderer/swapchain/vk_render_pass.h
git.filemode.normal_file
38
src/renderer/swapchain/vk_render_pass.h
git.filemode.normal_file
@@ -0,0 +1,38 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_render_pass.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef __MLX_VK_RENDER_PASS__
|
||||||
|
#define __MLX_VK_RENDER_PASS__
|
||||||
|
|
||||||
|
#include <volk.h>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
class RenderPass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void init();
|
||||||
|
void destroy() noexcept;
|
||||||
|
|
||||||
|
void begin();
|
||||||
|
void end();
|
||||||
|
|
||||||
|
inline VkRenderPass& operator()() noexcept { return _renderPass; }
|
||||||
|
inline VkRenderPass& get() noexcept { return _renderPass; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
VkRenderPass _renderPass = VK_NULL_HANDLE;
|
||||||
|
bool _is_running = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __MLX_VK_RENDER_PASS__
|
||||||
158
src/renderer/swapchain/vk_swapchain.cpp
git.filemode.normal_file
158
src/renderer/swapchain/vk_swapchain.cpp
git.filemode.normal_file
@@ -0,0 +1,158 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_swapchain.cpp :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include <renderer/core/render_core.h>
|
||||||
|
#include <platform/window.h>
|
||||||
|
#include <SDL2/SDL_vulkan.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
void SwapChain::init()
|
||||||
|
{
|
||||||
|
_swapChainSupport = querySwapChainSupport(Render_Core::get().getDevice().getPhysicalDevice());
|
||||||
|
|
||||||
|
VkSurfaceFormatKHR surfaceFormat = Render_Core::get().getSurface().chooseSwapSurfaceFormat(_swapChainSupport.formats);
|
||||||
|
VkPresentModeKHR presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
|
||||||
|
VkExtent2D extent = chooseSwapExtent(_swapChainSupport.capabilities);
|
||||||
|
|
||||||
|
uint32_t imageCount = _swapChainSupport.capabilities.minImageCount + 1;
|
||||||
|
if(_swapChainSupport.capabilities.maxImageCount > 0 && imageCount > _swapChainSupport.capabilities.maxImageCount)
|
||||||
|
imageCount = _swapChainSupport.capabilities.maxImageCount;
|
||||||
|
|
||||||
|
VkSwapchainCreateInfoKHR createInfo{};
|
||||||
|
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
||||||
|
createInfo.surface = Render_Core::get().getSurface().get();
|
||||||
|
|
||||||
|
createInfo.minImageCount = imageCount;
|
||||||
|
createInfo.imageFormat = surfaceFormat.format;
|
||||||
|
createInfo.imageColorSpace = surfaceFormat.colorSpace;
|
||||||
|
createInfo.imageExtent = extent;
|
||||||
|
createInfo.imageArrayLayers = 1;
|
||||||
|
createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||||
|
|
||||||
|
Queues::QueueFamilyIndices indices = Render_Core::get().getQueue().findQueueFamilies(Render_Core::get().getDevice().getPhysicalDevice());
|
||||||
|
uint32_t queueFamilyIndices[] = {indices.graphicsFamily.value(), indices.presentFamily.value()};
|
||||||
|
|
||||||
|
if(indices.graphicsFamily != indices.presentFamily)
|
||||||
|
{
|
||||||
|
createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
|
||||||
|
createInfo.queueFamilyIndexCount = 2;
|
||||||
|
createInfo.pQueueFamilyIndices = queueFamilyIndices;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
|
||||||
|
createInfo.preTransform = _swapChainSupport.capabilities.currentTransform;
|
||||||
|
createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||||
|
createInfo.presentMode = presentMode;
|
||||||
|
createInfo.clipped = VK_TRUE;
|
||||||
|
|
||||||
|
createInfo.oldSwapchain = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
VkDevice device = Render_Core::get().getDevice().get();
|
||||||
|
|
||||||
|
if(vkCreateSwapchainKHR(device, &createInfo, nullptr, &_swapChain) != VK_SUCCESS)
|
||||||
|
core::error::report(e_kind::fatal_error, "Vulkan : failed to create swapchain");
|
||||||
|
|
||||||
|
vkGetSwapchainImagesKHR(device, _swapChain, &imageCount, nullptr);
|
||||||
|
_swapChainImages.resize(imageCount);
|
||||||
|
vkGetSwapchainImagesKHR(device, _swapChain, &imageCount, _swapChainImages.data());
|
||||||
|
|
||||||
|
_swapChainImageFormat = surfaceFormat.format;
|
||||||
|
_swapChainExtent = extent;
|
||||||
|
|
||||||
|
_imageViews.resize(_swapChainImages.size());
|
||||||
|
|
||||||
|
for(size_t i = 0; i < _swapChainImages.size(); i++)
|
||||||
|
{
|
||||||
|
_imageViews.emplace_back();
|
||||||
|
_imageViews.back().init(this, _swapChainImages[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SwapChain::initFB()
|
||||||
|
{
|
||||||
|
_framebuffers.resize(_imageViews.size());
|
||||||
|
|
||||||
|
for(size_t i = 0; i < _imageViews.size(); i++)
|
||||||
|
{
|
||||||
|
_framebuffers.emplace_back();
|
||||||
|
_framebuffers.back().init(this, _imageViews[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SwapChain::SwapChainSupportDetails SwapChain::querySwapChainSupport(VkPhysicalDevice device)
|
||||||
|
{
|
||||||
|
SwapChain::SwapChainSupportDetails details;
|
||||||
|
VkSurfaceKHR surface = Render_Core::get().getSurface().get();
|
||||||
|
|
||||||
|
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &details.capabilities);
|
||||||
|
|
||||||
|
uint32_t formatCount = 0;
|
||||||
|
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, nullptr);
|
||||||
|
|
||||||
|
if(formatCount != 0)
|
||||||
|
{
|
||||||
|
details.formats.resize(formatCount);
|
||||||
|
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, details.formats.data());
|
||||||
|
}
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkExtent2D SwapChain::chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities)
|
||||||
|
{
|
||||||
|
if(capabilities.currentExtent.width != std::numeric_limits<uint32_t>::max())
|
||||||
|
return capabilities.currentExtent;
|
||||||
|
|
||||||
|
int width, height;
|
||||||
|
SDL_Vulkan_GetDrawableSize(Render_Core::get().getWindow()->getNativeWindow(), &width, &height);
|
||||||
|
|
||||||
|
VkExtent2D actualExtent = { static_cast<uint32_t>(width), static_cast<uint32_t>(height) };
|
||||||
|
|
||||||
|
actualExtent.width = std::clamp(actualExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
|
||||||
|
actualExtent.height = std::clamp(actualExtent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
|
||||||
|
|
||||||
|
return actualExtent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SwapChain::recreate()
|
||||||
|
{
|
||||||
|
destroyFB();
|
||||||
|
destroy();
|
||||||
|
Render_Core::get().getRenderPass().destroy();
|
||||||
|
|
||||||
|
init();
|
||||||
|
Render_Core::get().getRenderPass().init();
|
||||||
|
initFB();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SwapChain::destroyFB() noexcept
|
||||||
|
{
|
||||||
|
vkDeviceWaitIdle(Render_Core::get().getDevice().get());
|
||||||
|
|
||||||
|
for(size_t i = 0; i < _framebuffers.size(); i++)
|
||||||
|
_framebuffers[i].destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SwapChain::destroy() noexcept
|
||||||
|
{
|
||||||
|
vkDeviceWaitIdle(Render_Core::get().getDevice().get());
|
||||||
|
|
||||||
|
for(size_t i = 0; i < _imageViews.size(); i++)
|
||||||
|
_imageViews[i].destroy();
|
||||||
|
|
||||||
|
if(_swapChain != VK_NULL_HANDLE)
|
||||||
|
vkDestroySwapchainKHR(Render_Core::get().getDevice().get(), _swapChain, nullptr);
|
||||||
|
_swapChain = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
65
src/renderer/swapchain/vk_swapchain.h
git.filemode.normal_file
65
src/renderer/swapchain/vk_swapchain.h
git.filemode.normal_file
@@ -0,0 +1,65 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* vk_swapchain.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* 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 */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef __MLX_VK_SWAPCHAIN__
|
||||||
|
#define __MLX_VK_SWAPCHAIN__
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <volk.h>
|
||||||
|
#include "vk_imageview.h"
|
||||||
|
#include "vk_framebuffer.h"
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
class SwapChain
|
||||||
|
{
|
||||||
|
friend class FrameBuffer;
|
||||||
|
friend class ImageView;
|
||||||
|
friend class GraphicPipeline;
|
||||||
|
friend class RenderPass;
|
||||||
|
friend class RendererComponent;
|
||||||
|
|
||||||
|
public:
|
||||||
|
struct SwapChainSupportDetails
|
||||||
|
{
|
||||||
|
VkSurfaceCapabilitiesKHR capabilities;
|
||||||
|
std::vector<VkSurfaceFormatKHR> formats;
|
||||||
|
};
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void initFB();
|
||||||
|
void destroy() noexcept;
|
||||||
|
void destroyFB() noexcept;
|
||||||
|
|
||||||
|
void recreate();
|
||||||
|
|
||||||
|
SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device);
|
||||||
|
VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities);
|
||||||
|
|
||||||
|
inline SwapChainSupportDetails getSupport() noexcept { return _swapChainSupport; }
|
||||||
|
inline VkSwapchainKHR& operator()() noexcept { return _swapChain; }
|
||||||
|
inline VkSwapchainKHR& get() noexcept { return _swapChain; }
|
||||||
|
inline FrameBuffer& getFrameBuffer(int i) { return _framebuffers[i]; }
|
||||||
|
inline size_t getImagesNumber() const noexcept { return _swapChainImages.size(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
SwapChainSupportDetails _swapChainSupport;
|
||||||
|
VkSwapchainKHR _swapChain;
|
||||||
|
std::vector<VkImage> _swapChainImages;
|
||||||
|
VkFormat _swapChainImageFormat;
|
||||||
|
VkExtent2D _swapChainExtent;
|
||||||
|
std::vector<FrameBuffer> _framebuffers;
|
||||||
|
std::vector<ImageView> _imageViews;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __MLX_VK_SWAPCHAIN__
|
||||||
33
src/utils/non_copyable.h
git.filemode.normal_file
33
src/utils/non_copyable.h
git.filemode.normal_file
@@ -0,0 +1,33 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* non_copyable.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2022/10/08 19:20:13 by maldavid #+# #+# */
|
||||||
|
/* Updated: 2022/10/08 19:21:22 by maldavid ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef __MLX_NON_COPYABLE__
|
||||||
|
#define __MLX_NON_COPYABLE__
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
class non_copyable
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
non_copyable() = default;
|
||||||
|
virtual ~non_copyable() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
non_copyable(const non_copyable&) = delete;
|
||||||
|
non_copyable(non_copyable&&) noexcept = default;
|
||||||
|
non_copyable &operator=(const non_copyable&) = delete;
|
||||||
|
non_copyable &operator=(non_copyable&&) noexcept = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __MLX_NON_COPYABLE__
|
||||||
32
src/utils/singleton.h
git.filemode.normal_file
32
src/utils/singleton.h
git.filemode.normal_file
@@ -0,0 +1,32 @@
|
|||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* singleton.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2022/10/08 19:18:46 by maldavid #+# #+# */
|
||||||
|
/* Updated: 2022/10/08 19:22:07 by maldavid ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef __MLX_SINGLETON__
|
||||||
|
#define __MLX_SINGLETON__
|
||||||
|
|
||||||
|
#include "non_copyable.h"
|
||||||
|
|
||||||
|
namespace mlx
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
class Singleton : public non_copyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline static T& get()
|
||||||
|
{
|
||||||
|
static T instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __MLX_SINGLETON__
|
||||||
27
test/main.c
27
test/main.c
@@ -6,23 +6,34 @@
|
|||||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2022/10/04 17:55:21 by maldavid #+# #+# */
|
/* Created: 2022/10/04 17:55:21 by maldavid #+# #+# */
|
||||||
/* Updated: 2022/10/05 19:25:46 by maldavid ### ########.fr */
|
/* Updated: 2022/12/18 03:51:19 by maldavid ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "../includes/mlx.h"
|
#include "../includes/mlx.h"
|
||||||
|
|
||||||
|
int update(void *mlx)
|
||||||
|
{
|
||||||
|
static int i = 0;
|
||||||
|
|
||||||
|
puts("dude");
|
||||||
|
i++;
|
||||||
|
if (i > 1000000)
|
||||||
|
mlx_loop_end(mlx);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
void *win_ptr;
|
void *win_ptr;
|
||||||
int x;
|
void *mlx_ptr;
|
||||||
int y;
|
|
||||||
|
|
||||||
mlx_init();
|
mlx_ptr = mlx_init();
|
||||||
win_ptr = mlx_new_window(400, 400, "My window");
|
win_ptr = mlx_new_window(mlx_ptr, 400, 400, "My window");
|
||||||
mlx_mouse_get_pos(win_ptr, &x, &y);
|
mlx_loop_hook(mlx_ptr, update, mlx_ptr);
|
||||||
printf("%d, %d\n", x, y);
|
mlx_loop(mlx_ptr);
|
||||||
mlx_loop();
|
mlx_destroy_window(mlx_ptr, win_ptr);
|
||||||
|
mlx_destroy_display(mlx_ptr);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
clear && gcc main.c ../libMicroX.so `sdl2-config --cflags --libs` -lSDL2 && ./a.out
|
clear && gcc main.c ../libmlx.so -lSDL2 && ./a.out
|
||||||
|
|||||||
2739
third_party/volk.c
vendored
git.filemode.normal_file
2739
third_party/volk.c
vendored
git.filemode.normal_file
File diff suppressed because it is too large
Load Diff
1805
third_party/volk.h
vendored
git.filemode.normal_file
1805
third_party/volk.h
vendored
git.filemode.normal_file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user