git rm --cached
This commit is contained in:
Submodule MacroLibX deleted from 826740906f
17
MacroLibX/CONTRIBUTING.md
Normal file
17
MacroLibX/CONTRIBUTING.md
Normal file
@ -0,0 +1,17 @@
|
||||
# How to contribute to the MacroLibX
|
||||
|
||||
For any questions, suggestions or help [contact me](mailto:contact@kbz8.me)
|
||||
|
||||
## **Found a bug?**
|
||||
|
||||
* Avoid opening any new issues without having checked if your problem has already been reported. If there are no currently open issues that fit your problem's description, feel free to [add it](https://github.com/seekrs/MacroLibX/issues/new).
|
||||
|
||||
* When writing an issue make sure to include a clear title and description as well as having filled out all the necessary information: System info, OS, OS-Version, ...
|
||||
|
||||
* If possible add pictures of the issue.
|
||||
|
||||
## Contributing
|
||||
|
||||
Before thinking of adding a contribution, think. Is it necessary? Will this actually be a useful/required feature? Is your implementation good?
|
||||
Provide clear and documented explanation as to what was changed.
|
||||
|
20
MacroLibX/LICENSE
Normal file
20
MacroLibX/LICENSE
Normal file
@ -0,0 +1,20 @@
|
||||
MIT License
|
||||
Copyright (c) 2022-2024 kbz_8
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
96
MacroLibX/Makefile
Normal file
96
MacroLibX/Makefile
Normal file
@ -0,0 +1,96 @@
|
||||
# **************************************************************************** #
|
||||
# #
|
||||
# ::: :::::::: #
|
||||
# Makefile :+: :+: :+: #
|
||||
# +:+ +:+ +:+ #
|
||||
# By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ #
|
||||
# +#+#+#+#+#+ +#+ #
|
||||
# Created: 2022/10/04 16:43:41 by maldavid #+# #+# #
|
||||
# Updated: 2023/12/31 01:09:30 by maldavid ### ########.fr #
|
||||
# #
|
||||
# **************************************************************************** #
|
||||
|
||||
NAME = libmlx.so
|
||||
|
||||
SRCS = $(wildcard $(addsuffix /*.cpp, ./src/core))
|
||||
SRCS += $(wildcard $(addsuffix /*.cpp, ./src/platform))
|
||||
SRCS += $(wildcard $(addsuffix /*.cpp, ./src/renderer))
|
||||
SRCS += $(wildcard $(addsuffix /*.cpp, ./src/renderer/**))
|
||||
|
||||
OBJ_DIR = objs/makefile
|
||||
OBJS = $(addprefix $(OBJ_DIR)/, $(SRCS:.cpp=.o))
|
||||
|
||||
OS = $(shell uname -s)
|
||||
DEBUG ?= false
|
||||
TOOLCHAIN ?= clang
|
||||
IMAGES_OPTIMIZED ?= true
|
||||
FORCE_INTEGRATED_GPU ?= false
|
||||
GRAPHICS_MEMORY_DUMP ?= false
|
||||
|
||||
MODE = "release"
|
||||
|
||||
CXX = clang++
|
||||
|
||||
CXXFLAGS = -std=c++17 -O3 -fPIC -Wall -Wextra -Werror -DSDL_MAIN_HANDLED
|
||||
INCLUDES = -I./includes -I./src -I./third_party
|
||||
|
||||
LDLIBS =
|
||||
|
||||
ifeq ($(TOOLCHAIN), gcc)
|
||||
CXX = g++
|
||||
CXXFLAGS += -Wno-error=cpp
|
||||
else
|
||||
CXXFLAGS += -Wno-error=#warning
|
||||
endif
|
||||
|
||||
ifeq ($(OS), Darwin)
|
||||
LDLIBS += -L /opt/homebrew/lib -lSDL2
|
||||
CXXFLAGS += -I /opt/homebrew/include
|
||||
NAME = libmlx.dylib
|
||||
endif
|
||||
|
||||
ifeq ($(DEBUG), true)
|
||||
CXXFLAGS += -g -D DEBUG
|
||||
MODE = "debug"
|
||||
endif
|
||||
|
||||
ifeq ($(FORCE_INTEGRATED_GPU), true)
|
||||
CXXFLAGS += -D FORCE_INTEGRATED_GPU
|
||||
endif
|
||||
|
||||
ifeq ($(IMAGES_OPTIMIZED), true)
|
||||
CXXFLAGS += -D IMAGE_OPTIMIZED
|
||||
endif
|
||||
|
||||
ifeq ($(GRAPHICS_MEMORY_DUMP), true)
|
||||
CXXFLAGS += -D GRAPHICS_MEMORY_DUMP
|
||||
endif
|
||||
|
||||
RM = rm -rf
|
||||
|
||||
$(OBJ_DIR)/%.o: %.cpp
|
||||
@printf "\033[1;32m[compiling... "$(MODE)" "$(CXX)"]\033[1;00m "$<"\n"
|
||||
@$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@
|
||||
|
||||
all: $(NAME)
|
||||
|
||||
$(NAME): $(OBJ_DIR) $(OBJS)
|
||||
@printf "\033[1;32m[linking ... "$(MODE)"]\033[1;00m "$@"\n"
|
||||
@$(CXX) -shared -o $(NAME) $(OBJS) $(LDLIBS)
|
||||
@printf "\033[1;32m[build finished]\033[1;00m\n"
|
||||
|
||||
$(OBJ_DIR):
|
||||
@mkdir -p $(sort $(addprefix $(OBJ_DIR)/, $(dir $(SRCS))))
|
||||
@printf "\033[1;32m[created objs directory]\033[1;00m\n"
|
||||
|
||||
clean:
|
||||
@$(RM) $(OBJ_DIR)
|
||||
@printf "\033[1;32m[object files removed]\033[1;00m\n"
|
||||
|
||||
fclean: clean
|
||||
@$(RM) $(NAME)
|
||||
@printf "\033[1;32m["$(NAME)" removed]\033[1;00m\n"
|
||||
|
||||
re: fclean all
|
||||
|
||||
.PHONY: all clean fclean re
|
113
MacroLibX/README.md
Normal file
113
MacroLibX/README.md
Normal file
@ -0,0 +1,113 @@
|
||||
<div align="center">
|
||||
<img src="./res/logo.png" alt="drawing" width="200"/>
|
||||
<div align="center">
|
||||
<a href="https://github.com/seekrs/MacroLibX/actions/workflows/linux_clang.yml"><img src="https://github.com/seekrs/MacroLibX/actions/workflows/linux_clang.yml/badge.svg"></a>
|
||||
<a href="https://github.com/seekrs/MacroLibX/actions/workflows/linux_gcc.yml"><img src="https://github.com/seekrs/MacroLibX/actions/workflows/linux_gcc.yml/badge.svg"></a>
|
||||
<a href="https://github.com/seekrs/MacroLibX/actions/workflows/macos_x86.yml"><img src="https://github.com/seekrs/MacroLibX/actions/workflows/macos_x86.yml/badge.svg"></a>
|
||||
</div>
|
||||
<div align="center">
|
||||
<a href="https://github.com/seekrs/MacroLibX/actions/workflows/windows.yml"><img src="https://github.com/seekrs/MacroLibX/actions/workflows/windows.yml/badge.svg"></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
###### MacroLibX, a rewrite of 42 School's MiniLibX using SDL2 and Vulkan.
|
||||
The goal of this version is to provide a light, fast, and modern graphical tool while keeping the same API.
|
||||
|
||||
## 🌟 Features
|
||||
|
||||
### 🚀 Performances
|
||||
Built on top of Vulkan, the MacroLibX takes advantage of its very low-level nature to achieve high performance with great control over available resources.
|
||||
|
||||
### 💻 Cross-Platform
|
||||
Designed to be totally cross-platform, it can run on any SDL2-supported platform that supports Vulkan (even the Nintendo Switch ! theoretically... ).
|
||||
|
||||
### 🗿 Close to the old minilibx
|
||||
One of the guidelines of this lib was to get as close as possible to the old minilibx API, and therefore to the educational choices of the old minilibx.
|
||||
|
||||
### 📖 It's all FOSS
|
||||
Everything in this repo is entirely free and open source, all available under the MIT license (even the third-party libraries used).
|
||||
|
||||
### 🔍 Valgrind suppressions file
|
||||
Experimental for now, a [suppressions file for valgrind](./valgrind.supp) is given to remove potential leaks comming from Xorg, Nvidia drivers, SDL2, or any other tool which the user has no control. It is far from perfect at the moment and may allow some leaks but it will block the majority.
|
||||
|
||||
### ⛔ Error system
|
||||
Strong error handling informing the user of problems with their code and even capable of informing them of graphics memory leaks that tools like Valgrind cannot detect.
|
||||
|
||||
## 🖥️ Installation
|
||||
|
||||
### Dependencies
|
||||
You first need to install the proper dependencies for your operating-system.
|
||||
|
||||
#### 🐧 Linux
|
||||
Here are a few common cases for different Linux distributions:
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
For <a href="https://ubuntu.com">Ubuntu</a>/<a href="https://debian.org">Debian</a>-based distros:
|
||||
</summary>
|
||||
<pre><code><!--
|
||||
-->sudo apt update
|
||||
sudo apt install libsdl2-2.0-0 libsdl2-dev build-essential
|
||||
</code></pre>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
For <a href="https://archlinux.org">ArchLinux</a>-based distros:
|
||||
</summary>
|
||||
<pre><code>sudo pacman -S sdl2</code></pre>
|
||||
</details>
|
||||
|
||||
<br>
|
||||
Note that you need to have up do date video drivers with <code>libvulkan.so</code> installed.
|
||||
|
||||
#### 🍎 macOS
|
||||
[MacroLibX](#) on macOS requires [SDL2](#) and [MoltenVK](https://github.com/KhronosGroup/MoltenVK). You can install both using the [Homebrew](https://brew.sh) package manager:
|
||||
```sh
|
||||
brew install molten-vk
|
||||
brew install SDL2
|
||||
```
|
||||
|
||||
### 🪟 Windows
|
||||
To build on Windows you may need to use the [xmake](https://xmake.io) build. [Here's](./XMAKE_BUILD.md) how you can use it.
|
||||
|
||||
### Clone and Build
|
||||
Finally, you can clone the Git repository. When inside it, run the GNU `make` command to compile MacroLibX.
|
||||
```bash
|
||||
git clone https://github.com/seekrs/MacroLibX.git
|
||||
cd MacroLibX
|
||||
make
|
||||
```
|
||||
|
||||
## 🔨 Compile your project
|
||||
To compile your project with MacroLibX, you just provide the shared library path in your compilation/linking command:
|
||||
|
||||
```sh
|
||||
clang myApp.c /path/to/MacroLibX/libmlx.so -lSDL2
|
||||
```
|
||||
|
||||
And you can enjoy your project
|
||||
|
||||
<p align="center">
|
||||
<img src="./res/screenshot_test.png" alt="drawing" width="400"/>
|
||||
</p>
|
||||
|
||||
## ⚙️ Some compilation configurations
|
||||
|
||||
### 📦 Compile mode
|
||||
By default the mlx is built in release mode but you can switch to debug by using `make DEBUG=true`.
|
||||
|
||||
### 🛠️ Set the toolchain
|
||||
If you want to use `GCC` to build the mlx you can use `make TOOLCHAIN=gcc`
|
||||
|
||||
### ⚠️⚠️⚠️ 🖼️ Image optimisations ⚠️⚠️⚠️
|
||||
If you run into glitches when writing or reading pixels from images you can turn off images optimisations by using `make IMAGES_OPTIMIZED=false`.
|
||||
|
||||
### 🖥️ Force the integrated GPU (not recommended)
|
||||
You can force the mlx to use your integrated GPU by using `make FORCE_INTEGRATED_GPU=true`. Note that there are a lot of chances that your application crashes by using that.
|
||||
|
||||
### 💽 Dump the graphics memory
|
||||
The mlx can dump it's graphics memory use to json files every two seconds by enabling this option `make GRAPHICS_MEMORY_DUMP=true`.
|
||||
|
||||
## License
|
||||
This project and all its files, even the [`third_party`](./third_party) directory or unless otherwise mentionned, are licenced under the [MIT license](./LICENSE).
|
47
MacroLibX/XMAKE_BUILD.md
Normal file
47
MacroLibX/XMAKE_BUILD.md
Normal file
@ -0,0 +1,47 @@
|
||||
# 🏗️ xmake build
|
||||
To build on Windows (if you don't use [WSL](https://learn.microsoft.com/en-us/windows/wsl/install)), the MacroLibX uses [xmake](https://xmake.io), a build system which will download and compile all dependencies it won't find on your computer.
|
||||
|
||||
## 💾 Install xmake
|
||||
You can find how to install it on your system [here](https://xmake.io/#/guide/installation). Note that you can also download a [portable version](https://github.com/xmake-io/xmake/releases) of xmake if you wish not to install it.
|
||||
|
||||
## ⚙️ Configure the MacroLibX build
|
||||
Just as the Makfile build system, you can configure how xmake should build the MacroLibX. The base command to configure it is `xmake config [opts...]` or `xmake f [opts...]`.
|
||||
|
||||
### 📦 Compile mode
|
||||
You can configure xmake to build the mlx in debug mode or in release mode (release mode is enabled by default). To do so you can use `xmake config --mode=debug` or `xmake config --mode=release`.
|
||||
|
||||
### 🛠️ Set the toolchain
|
||||
To change the compilation toolchain you can use `xmake config --toolchain=[gcc|clang|...]`
|
||||
|
||||
### ⚠️⚠️⚠️ 🖼️ Image optimisations ⚠️⚠️⚠️
|
||||
If you run into glitches when writing or reading pixels from images you can turn off images optimisations by using `xmake config --images_optimized=n`.
|
||||
|
||||
### 🖥️ Force the integrated GPU (not recommended)
|
||||
You can force the mlx to use your integrated GPU using `xmake config --force_integrated_gpu=y`. Note that there are a lot of chances that your application crashes by using that.
|
||||
|
||||
### 💽 Dump the graphics memory
|
||||
The mlx can dump it's graphics memory use to json files every two seconds by enabling this option `xmake config --graphics_memory_dump=y`.
|
||||
|
||||
### 🪛 A possible build configuration
|
||||
As a configuration example here's how the command can look like `xmake config --mode=debug --toolchain=clang --graphics_memory_dump=y --images_optimized=n`
|
||||
|
||||
## 🚧 Build the lib
|
||||
|
||||
### Compile using command-line (first method)
|
||||
Once you're ready to compile the lib, run `xmake` (or `xmake -jX` if you wish not to use all your computer threads, with X being the number of threads you wish to use) and watch as the lib compiles.
|
||||
|
||||
### Generate a project (second method)
|
||||
xmake can also generate a project file for another tool:
|
||||
* Visual Studio : `xmake project -k vs`
|
||||
* CMakeLists.txt (which you can open in CLion and more) : `xmake project -k cmake`
|
||||
* Makefile : `xmake project -k make`
|
||||
* Ninja : `xmake project -k ninja`
|
||||
* XCode : `xmake project -k xcode`
|
||||
|
||||
You should now be able to open the project file with the tool of your choice.
|
||||
|
||||
## 😋 Enjoy
|
||||
Enjoy you project built with the mlx
|
||||
<p align="center">
|
||||
<img src="./res/screenshot_test_windows.png" alt="drawing" width="400"/>
|
||||
</p>
|
642
MacroLibX/compile_commands.json
Normal file
642
MacroLibX/compile_commands.json
Normal file
@ -0,0 +1,642 @@
|
||||
[
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/text_pipeline.o",
|
||||
"src/renderer/text_pipeline.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/text_pipeline.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/text_pipeline.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/buffers/vk_vbo.o",
|
||||
"src/renderer/buffers/vk_vbo.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/buffers/vk_vbo.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/buffers/vk_vbo.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/pixel_put.o",
|
||||
"src/renderer/pixel_put.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/pixel_put.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/pixel_put.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/core/graphics.o",
|
||||
"src/core/graphics.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/core/graphics.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/core/graphics.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/buffers/vk_ubo.o",
|
||||
"src/renderer/buffers/vk_ubo.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/buffers/vk_ubo.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/buffers/vk_ubo.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/platform/inputs.o",
|
||||
"src/platform/inputs.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/platform/inputs.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/platform/inputs.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/renderer.o",
|
||||
"src/renderer/renderer.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/renderer.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/renderer.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/text_library.o",
|
||||
"src/renderer/text_library.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/text_library.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/text_library.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/buffers/vk_buffer.o",
|
||||
"src/renderer/buffers/vk_buffer.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/buffers/vk_buffer.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/buffers/vk_buffer.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/command/cmd_manager.o",
|
||||
"src/renderer/command/cmd_manager.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/command/cmd_manager.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/command/cmd_manager.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/core/vk_device.o",
|
||||
"src/renderer/core/vk_device.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/core/vk_device.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/core/vk_device.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/command/vk_cmd_buffer.o",
|
||||
"src/renderer/command/vk_cmd_buffer.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/command/vk_cmd_buffer.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/command/vk_cmd_buffer.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/core/render_core.o",
|
||||
"src/renderer/core/render_core.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/core/render_core.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/core/render_core.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/command/vk_cmd_pool.o",
|
||||
"src/renderer/command/vk_cmd_pool.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/command/vk_cmd_pool.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/command/vk_cmd_pool.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/core/vk_instance.o",
|
||||
"src/renderer/core/vk_instance.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/core/vk_instance.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/core/vk_instance.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/core/vk_semaphore.o",
|
||||
"src/renderer/core/vk_semaphore.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/core/vk_semaphore.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/core/vk_semaphore.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/core/vk_queues.o",
|
||||
"src/renderer/core/vk_queues.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/core/vk_queues.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/core/vk_queues.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/core/vk_validation_layers.o",
|
||||
"src/renderer/core/vk_validation_layers.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/core/vk_validation_layers.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/core/vk_validation_layers.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/core/vk_surface.o",
|
||||
"src/renderer/core/vk_surface.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/core/vk_surface.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/core/vk_surface.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/core/vk_fence.o",
|
||||
"src/renderer/core/vk_fence.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/core/vk_fence.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/core/vk_fence.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/descriptors/vk_descriptor_pool.o",
|
||||
"src/renderer/descriptors/vk_descriptor_pool.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/descriptors/vk_descriptor_pool.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/descriptors/vk_descriptor_pool.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/images/texture_atlas.o",
|
||||
"src/renderer/images/texture_atlas.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/images/texture_atlas.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/images/texture_atlas.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/descriptors/vk_descriptor_set.o",
|
||||
"src/renderer/descriptors/vk_descriptor_set.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/descriptors/vk_descriptor_set.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/descriptors/vk_descriptor_set.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/swapchain/vk_framebuffer.o",
|
||||
"src/renderer/swapchain/vk_framebuffer.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/swapchain/vk_framebuffer.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/swapchain/vk_framebuffer.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/pipeline/pipeline.o",
|
||||
"src/renderer/pipeline/pipeline.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/pipeline/pipeline.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/pipeline/pipeline.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/images/vk_image.o",
|
||||
"src/renderer/images/vk_image.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/images/vk_image.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/images/vk_image.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/descriptors/vk_descriptor_set_layout.o",
|
||||
"src/renderer/descriptors/vk_descriptor_set_layout.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/descriptors/vk_descriptor_set_layout.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/descriptors/vk_descriptor_set_layout.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/swapchain/vk_imageview.o",
|
||||
"src/renderer/swapchain/vk_imageview.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/swapchain/vk_imageview.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/swapchain/vk_imageview.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/swapchain/vk_swapchain.o",
|
||||
"src/renderer/swapchain/vk_swapchain.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/swapchain/vk_swapchain.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/swapchain/vk_swapchain.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/swapchain/vk_render_pass.o",
|
||||
"src/renderer/swapchain/vk_render_pass.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/swapchain/vk_render_pass.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/swapchain/vk_render_pass.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/platform/window.o",
|
||||
"src/platform/window.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/platform/window.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/platform/window.o"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/usr/bin/clang++",
|
||||
"-std=c++17",
|
||||
"-O3",
|
||||
"-fPIC",
|
||||
"-D",
|
||||
"IMAGE_OPTIMIZED",
|
||||
"-I./includes",
|
||||
"-I./src",
|
||||
"-I./third_party",
|
||||
"-c",
|
||||
"-o",
|
||||
"src/renderer/images/texture.o",
|
||||
"src/renderer/images/texture.cpp"
|
||||
],
|
||||
"directory": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX",
|
||||
"file": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/images/texture.cpp",
|
||||
"output": "/home/kbz_8/Documents/Programmation/42/other/MacroLibX/src/renderer/images/texture.o"
|
||||
}
|
||||
]
|
BIN
MacroLibX/example/42_logo.png
Normal file
BIN
MacroLibX/example/42_logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.2 KiB |
BIN
MacroLibX/example/Test
Executable file
BIN
MacroLibX/example/Test
Executable file
Binary file not shown.
8
MacroLibX/example/build.sh
Executable file
8
MacroLibX/example/build.sh
Executable file
@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ $(uname -s) = 'Darwin' ]; then
|
||||
clang main.c ../libmlx.dylib -L /opt/homebrew/lib -lSDL2 -g;
|
||||
else
|
||||
clang main.c ../libmlx.so -lSDL2 -g;
|
||||
fi
|
||||
|
BIN
MacroLibX/example/font.ttf
Normal file
BIN
MacroLibX/example/font.ttf
Normal file
Binary file not shown.
122
MacroLibX/example/main.c
Normal file
122
MacroLibX/example/main.c
Normal file
@ -0,0 +1,122 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* main.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/04 17:55:21 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/03 12:29:31 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "../includes/mlx.h"
|
||||
|
||||
typedef struct s_mlx
|
||||
{
|
||||
void *mlx;
|
||||
void *win;
|
||||
void *logo;
|
||||
void *img;
|
||||
} t_mlx;
|
||||
|
||||
int update(void *param)
|
||||
{
|
||||
static int i = 0;
|
||||
int j;
|
||||
int k;
|
||||
t_mlx *mlx;
|
||||
|
||||
mlx = (t_mlx *)param;
|
||||
mlx_put_image_to_window(mlx->mlx, mlx->win, mlx->logo, 100, 100);
|
||||
mlx_put_image_to_window(mlx->mlx, mlx->win, mlx->img, 150, 60);
|
||||
if (i == 0)
|
||||
mlx_set_font_scale(mlx->mlx, mlx->win, "font.ttf", 16.f);
|
||||
mlx_string_put(mlx->mlx, mlx->win, 20, 50, 0xFFFFFFFF, "that's a text");
|
||||
j = 0;
|
||||
k = 0;
|
||||
while (j++ < 400)
|
||||
{
|
||||
mlx_pixel_put(mlx->mlx, mlx->win, j, j, 0xFFFF0000 + k);
|
||||
mlx_pixel_put(mlx->mlx, mlx->win, 399 - j, j, 0xFF0000FF);
|
||||
k += (k < 255);
|
||||
}
|
||||
if (++i == 5000)
|
||||
mlx_clear_window(mlx->mlx, mlx->win);
|
||||
if (i == 7000)
|
||||
mlx_set_font_scale(mlx->mlx, mlx->win, "default", 16.f);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void *create_image(t_mlx *mlx)
|
||||
{
|
||||
unsigned char pixel[4];
|
||||
int i[3];
|
||||
void *img;
|
||||
|
||||
memset(i, 0, sizeof(int) * 3);
|
||||
img = mlx_new_image(mlx->mlx, 100, 100);
|
||||
while (i[0] < (100 * 100) * 4)
|
||||
{
|
||||
if (i[0] < 10000 || i[0] > 20000)
|
||||
{
|
||||
pixel[0] = i[0];
|
||||
pixel[1] = i[1];
|
||||
pixel[2] = i[2];
|
||||
pixel[3] = 0x99;
|
||||
mlx_set_image_pixel(mlx->mlx, img, i[1], i[2], *((int *)pixel));
|
||||
}
|
||||
i[0] += 4;
|
||||
i[1]++;
|
||||
if (i[1] >= 100)
|
||||
{
|
||||
i[1] = 0;
|
||||
i[2]++;
|
||||
}
|
||||
}
|
||||
return (img);
|
||||
}
|
||||
|
||||
int key_hook(int key, void *param)
|
||||
{
|
||||
if (key == 41)
|
||||
mlx_loop_end(((t_mlx *)param)->mlx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int window_hook(int event, void *param)
|
||||
{
|
||||
if (event == 0)
|
||||
mlx_loop_end(((t_mlx *)param)->mlx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
t_mlx mlx;
|
||||
void *img;
|
||||
int w;
|
||||
int h;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
mlx.mlx = mlx_init();
|
||||
mlx.win = mlx_new_window(mlx.mlx, 400, 400, "My window");
|
||||
mlx_on_event(mlx.mlx, mlx.win, MLX_KEYDOWN, key_hook, &mlx);
|
||||
mlx_on_event(mlx.mlx, mlx.win, MLX_WINDOW_EVENT, window_hook, &mlx);
|
||||
mlx.logo = mlx_png_file_to_image(mlx.mlx, "42_logo.png", &w, &h);
|
||||
mlx_pixel_put(mlx.mlx, mlx.win, 200, 10, 0xFFFF00FF);
|
||||
mlx_put_image_to_window(mlx.mlx, mlx.win, mlx.logo, 10, 190);
|
||||
mlx.img = create_image(&mlx);
|
||||
mlx_string_put(mlx.mlx, mlx.win, 20, 20, 0xFFFF2000, \
|
||||
"that text will disappear");
|
||||
mlx_loop_hook(mlx.mlx, update, &mlx);
|
||||
mlx_loop(mlx.mlx);
|
||||
mlx_destroy_image(mlx.mlx, mlx.img);
|
||||
mlx_destroy_image(mlx.mlx, mlx.logo);
|
||||
mlx_destroy_window(mlx.mlx, mlx.win);
|
||||
mlx_destroy_display(mlx.mlx);
|
||||
return (0);
|
||||
}
|
4
MacroLibX/example/run.sh
Executable file
4
MacroLibX/example/run.sh
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
bash ./build.sh
|
||||
./a.out
|
365
MacroLibX/includes/mlx.h
Normal file
365
MacroLibX/includes/mlx.h
Normal file
@ -0,0 +1,365 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* mlx.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/04 16:56:35 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/27 17:19:50 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
// MacroLibX official repo https://github.com/seekrs/MacroLibX
|
||||
|
||||
#ifndef __MACRO_LIB_X_H__
|
||||
#define __MACRO_LIB_X_H__
|
||||
|
||||
#include "mlx_profile.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MLX_KEYDOWN = 0,
|
||||
MLX_KEYUP = 1,
|
||||
MLX_MOUSEDOWN = 2,
|
||||
MLX_MOUSEUP = 3,
|
||||
MLX_MOUSEWHEEL = 4,
|
||||
MLX_WINDOW_EVENT = 5
|
||||
} mlx_event_type;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initializes the MLX internal application
|
||||
*
|
||||
* @return (void*) An opaque pointer to the internal MLX application or NULL (0x0) in case of error
|
||||
*/
|
||||
MLX_API void* mlx_init();
|
||||
|
||||
|
||||
/**
|
||||
* @brief Creates a new window
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
* @param w Width of the window
|
||||
* @param h Height of the window
|
||||
* @param title Title of the window
|
||||
*
|
||||
* @return (void*) An opaque pointer to the internal MLX window or NULL (0x0) in case of error
|
||||
*/
|
||||
MLX_API void* mlx_new_window(void* mlx, int w, int h, const char* title);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Gives a function to be executed at each loop turn
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
* @param f The function
|
||||
* @param param Param to give to the function passed
|
||||
*
|
||||
* @return (int) Always return 0, made this to copy the behaviour of the original MLX
|
||||
*/
|
||||
MLX_API int mlx_loop_hook(void* mlx, int (*f)(void*), void* param);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Starts the internal main loop
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
*
|
||||
* @return (int) Always return 0, made this to copy the behaviour of the original MLX
|
||||
*/
|
||||
MLX_API int mlx_loop(void* mlx);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Ends the internal main loop
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
*
|
||||
* @return (int) Always return 0, made this to copy the behaviour of the original MLX
|
||||
*/
|
||||
MLX_API int mlx_loop_end(void* mlx);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Shows mouse cursor
|
||||
*
|
||||
* @return (int) Always return 0, made this to copy the behaviour of the original MLX
|
||||
*/
|
||||
MLX_API int mlx_mouse_show();
|
||||
|
||||
|
||||
/**
|
||||
* @brief Hides mouse cursor
|
||||
*
|
||||
* @return (int) Always return 0, made this to copy the behaviour of the original MLX
|
||||
*/
|
||||
MLX_API int mlx_mouse_hide();
|
||||
|
||||
|
||||
/**
|
||||
* @brief Moves cursor to givent position
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
* @param win Internal window from which cursor moves
|
||||
* @param x X coordinate
|
||||
* @param y Y coordinate
|
||||
*
|
||||
* @return (int) Always return 0, made this to copy the behaviour of the original MLX
|
||||
*/
|
||||
MLX_API int mlx_mouse_move(void* mlx, void* win, int x, int y);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get cursor's position
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
* @param x Get x coordinate
|
||||
* @param y Get y coordinate
|
||||
*
|
||||
* @return (int) Always return 0, made this to copy the behaviour of the original MLX
|
||||
*/
|
||||
MLX_API int mlx_mouse_get_pos(void* mlx, int* x, int* y);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Gives a function to be executed on event type
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
* @param win Internal window
|
||||
* @param event Event type (see union on top of this file)
|
||||
* @param f Function to be executed
|
||||
* @param param Parameter given to the function
|
||||
*
|
||||
* @return (int) Always return 0, made this to copy the behaviour of the original MLX
|
||||
*/
|
||||
MLX_API int mlx_on_event(void* mlx, void* win, mlx_event_type event, int (*f)(int, void*), void* param);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Put a pixel in the window
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
* @param win Internal window
|
||||
* @param x X coordinate
|
||||
* @param y Y coordinate
|
||||
* @param color Color of the pixel (coded on 3 bytes in an int, 0x00RRGGBB)
|
||||
*
|
||||
* Note : If your're reading pixel colors from an image, don't forget to shift them
|
||||
* one byte to the right as image pixels are encoded as 0xRRGGBBAA and pixel put takes 0x00RRGGBB.
|
||||
*
|
||||
* @return (int) Always return 0, made this to copy the behaviour of the original MLX
|
||||
*/
|
||||
MLX_API int mlx_pixel_put(void* mlx, void* win, int x, int y, int color);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Create a new empty image
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
* @param width Width of the image
|
||||
* @param height Height of the image
|
||||
*
|
||||
* @return (void*) An opaque pointer to the internal image or NULL (0x0) in case of error
|
||||
*/
|
||||
MLX_API void* mlx_new_image(void* mlx, int width, int height);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get image pixel data
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
* @param img Internal image
|
||||
* @param x X coordinate in the image
|
||||
* @param y Y coordinate in the image
|
||||
*
|
||||
* @return (int) Return the pixel data
|
||||
*
|
||||
* /!\ If you run into glitches when writing or reading pixels from images /!\
|
||||
* You need to add IMAGES_OPTIMIZED=false to your make mlx command
|
||||
* ```
|
||||
* ~ git clone https://github.com/seekrs/MacroLibX.git
|
||||
* ~ cd MacroLibX
|
||||
* ~ make IMAGES_OPTIMIZED=false
|
||||
* ```
|
||||
*/
|
||||
MLX_API int mlx_get_image_pixel(void* mlx, void* img, int x, int y);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set image pixel data
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
* @param img Internal image
|
||||
* @param x X coordinate in the image
|
||||
* @param y Y coordinate in the image
|
||||
* @param color Color of the pixel to set
|
||||
*
|
||||
* @return (void)
|
||||
*
|
||||
* /!\ If you run into glitches when writing or reading pixels from images /!\
|
||||
* You need to add IMAGES_OPTIMIZED=false to your make mlx command
|
||||
* ```
|
||||
* ~ git clone https://github.com/seekrs/MacroLibX.git
|
||||
* ~ cd MacroLibX
|
||||
* ~ make IMAGES_OPTIMIZED=false
|
||||
* ```
|
||||
*/
|
||||
MLX_API void mlx_set_image_pixel(void* mlx, void* img, int x, int y, int color);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Put image to the given window
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
* @param win Internal window
|
||||
* @param img Internal image
|
||||
* @param x X coordinate
|
||||
* @param y Y coordinate
|
||||
*
|
||||
* @return (int) Always return 0, made this to copy the behaviour of the original MLX
|
||||
*/
|
||||
MLX_API int mlx_put_image_to_window(void* mlx, void* win, void* img, int x, int y);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Destroys internal image
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
* @param img Internal image
|
||||
*
|
||||
* @return (int) Always return 0, made this to copy the behaviour of the original MLX
|
||||
*/
|
||||
MLX_API int mlx_destroy_image(void* mlx, void* img);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Create a new image from a png file
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
* @param filename Path to the png file
|
||||
* @param width Get the width of the image
|
||||
* @param heigth Get the height of the image
|
||||
*
|
||||
* @return (void*) An opaque pointer to the internal image or NULL (0x0) in case of error
|
||||
*/
|
||||
MLX_API void* mlx_png_file_to_image(void* mlx, char* filename, int* width, int* height);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Create a new image from a jpg file
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
* @param filename Path to the jpg file
|
||||
* @param width Get the width of the image
|
||||
* @param heigth Get the height of the image
|
||||
*
|
||||
* @return (void*) An opaque pointer to the internal image or NULL (0x0) in case of error
|
||||
*/
|
||||
MLX_API void* mlx_jpg_file_to_image(void* mlx, char* filename, int* width, int* height);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Create a new image from a bmp file
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
* @param filename Path to the bmp file
|
||||
* @param width Get the width of the image
|
||||
* @param heigth Get the height of the image
|
||||
*
|
||||
* @return (void*) An opaque pointer to the internal image or NULL (0x0) in case of error
|
||||
*/
|
||||
MLX_API void* mlx_bmp_file_to_image(void* mlx, char* filename, int* width, int* height);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Put text in given window
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
* @param win Internal window
|
||||
* @param x X coordinate
|
||||
* @param y Y coordinate
|
||||
* @param color Color of the pixel (coded on 3 bytes in an int, 0x00RRGGBB)
|
||||
* @param str Text to put
|
||||
*
|
||||
* @return (int) Always return 0, made this to copy the behaviour of the original MLX
|
||||
*/
|
||||
MLX_API int mlx_string_put(void* mlx, void* win, int x, int y, int color, char* str);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Loads a font to be used by `mlx_string_put`
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
* @param win Internal window
|
||||
* @param filepath Filepath to the font or "default" to reset to the embedded font
|
||||
*
|
||||
* @return (void)
|
||||
*/
|
||||
MLX_API void mlx_set_font(void* mlx, void* win, char* filepath);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Loads a font to be used by `mlx_string_put` and scales it
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
* @param win Internal window
|
||||
* @param filepath Filepath to the font or "default" to reset to the embedded font
|
||||
* @param scale Scale to apply to the font
|
||||
*
|
||||
* @return (void)
|
||||
*/
|
||||
MLX_API void mlx_set_font_scale(void* mlx, void* win, char* filepath, float scale);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Clears the given window (resets all rendered data)
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
* @param win Internal window
|
||||
*
|
||||
* @return (int) Always return 0, made this to copy the behaviour of the original MLX
|
||||
*/
|
||||
MLX_API int mlx_clear_window(void* mlx, void* win);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Destroys internal window
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
* @param win Internal window
|
||||
*
|
||||
* @return (int) Always return 0, made this to copy the behaviour of the original MLX
|
||||
*/
|
||||
MLX_API int mlx_destroy_window(void* mlx, void* win);
|
||||
|
||||
/**
|
||||
* @brief Destroy internal MLX application
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
*
|
||||
* @return (int) Always return 0, made this to copy the behaviour of the original MLX
|
||||
*/
|
||||
MLX_API int mlx_destroy_display(void* mlx);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get screen size
|
||||
*
|
||||
* @param mlx Internal MLX application
|
||||
* @param x Get X size
|
||||
* @param y Get Y size
|
||||
*
|
||||
* @return (int) Always return 0, made this to copy the behaviour of the original MLX
|
||||
*/
|
||||
MLX_API int mlx_get_screens_size(void* mlx, int* w, int* h);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
215
MacroLibX/includes/mlx_profile.h
Normal file
215
MacroLibX/includes/mlx_profile.h
Normal file
@ -0,0 +1,215 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* mlx_profile.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/11/10 08:49:17 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/03 15:33:35 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_PROFILE__
|
||||
#define __MLX_PROFILE__
|
||||
|
||||
// Try to identify the compiler
|
||||
#if defined(__BORLANDC__)
|
||||
#define MLX_COMPILER_BORDLAND
|
||||
#elif defined(__clang__)
|
||||
#define MLX_COMPILER_CLANG
|
||||
#ifdef __MINGW32__
|
||||
#define MLX_COMPILER_MINGW
|
||||
#ifdef __MINGW64_VERSION_MAJOR
|
||||
#define MLX_COMPILER_MINGW_W64
|
||||
#endif
|
||||
#endif
|
||||
#elif defined(__GNUC__) || defined(__MINGW32__)
|
||||
#define MLX_COMPILER_GCC
|
||||
#ifdef __MINGW32__
|
||||
#define MLX_COMPILER_MINGW
|
||||
#ifdef __MINGW64_VERSION_MAJOR
|
||||
#define MLX_COMPILER_MINGW_W64
|
||||
#endif
|
||||
#endif
|
||||
#elif defined(__INTEL_COMPILER) || defined(__ICL)
|
||||
#define MLX_COMPILER_INTEL
|
||||
#elif defined(_MSC_VER)
|
||||
#define MLX_COMPILER_MSVC
|
||||
#else
|
||||
#define MLX_COMPILER_UNKNOWN
|
||||
#warning "This compiler is not fully supported"
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#define MLX_PLAT_WINDOWS
|
||||
#elif defined(__linux__)
|
||||
#define MLX_PLAT_LINUX
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
#define MLX_PLAT_MACOS
|
||||
#elif defined(unix) || defined(__unix__) || defined(__unix)
|
||||
#define MLX_PLAT_UNIX
|
||||
#else
|
||||
#error "Unknown environment (not Windows, not Linux, not MacOS, not Unix)"
|
||||
#endif
|
||||
|
||||
#ifdef MLX_PLAT_WINDOWS
|
||||
#ifdef MLX_COMPILER_MSVC
|
||||
#ifdef MLX_BUILD
|
||||
#define MLX_API __declspec(dllexport)
|
||||
#else
|
||||
#define MLX_API __declspec(dllimport)
|
||||
#endif
|
||||
#elif defined(MLX_COMPILER_GCC)
|
||||
#ifdef MLX_BUILD
|
||||
#define MLX_API __attribute__((dllexport))
|
||||
#else
|
||||
#define MLX_API __attribute__((dllimport))
|
||||
#endif
|
||||
#else
|
||||
#define MLX_API
|
||||
#endif
|
||||
#elif defined(MLX_COMPILER_GCC)
|
||||
#define MLX_API __attribute__((visibility("default")))
|
||||
#else
|
||||
#define MLX_API
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__)
|
||||
#define MLX_FUNC_SIG __PRETTY_FUNCTION__
|
||||
#elif defined(__DMC__) && (__DMC__ >= 0x810)
|
||||
#define MLX_FUNC_SIG __PRETTY_FUNCTION__
|
||||
#elif (defined(__FUNCSIG__) || (_MSC_VER))
|
||||
#define MLX_FUNC_SIG __FUNCSIG__
|
||||
#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500))
|
||||
#define MLX_FUNC_SIG __FUNCTION__
|
||||
#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)
|
||||
#define MLX_FUNC_SIG __FUNC__
|
||||
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
|
||||
#define MLX_FUNC_SIG __func__
|
||||
#elif defined(__cplusplus) && (__cplusplus >= 201103)
|
||||
#define MLX_FUNC_SIG __func__
|
||||
#else
|
||||
#define MLX_FUNC_SIG "Unknown function"
|
||||
#endif
|
||||
|
||||
#ifndef __cplusplus // if we compile in C
|
||||
#ifdef __STDC__
|
||||
#ifdef __STDC_VERSION__
|
||||
#if __STDC_VERSION__ == 199409L
|
||||
#define MLX_C_VERSION 1994
|
||||
#elif __STDC_VERSION__ == 199901L
|
||||
#define MLX_C_VERSION 1999
|
||||
#elif __STDC_VERSION__ == 201112L
|
||||
#define MLX_C_VERSION 2011
|
||||
#elif __STDC_VERSION__ == 201710L
|
||||
#define MLX_C_VERSION 2017
|
||||
#elif __STDC_VERSION__ == 202311L
|
||||
#define MLX_C_VERSION 2023
|
||||
#else
|
||||
#define MLX_C_VERSION 0
|
||||
#endif
|
||||
#else
|
||||
#define MLX_C_VERSION 0
|
||||
#endif
|
||||
#else
|
||||
#define MLX_C_VERSION 0
|
||||
#endif
|
||||
#else
|
||||
#define MLX_C_VERSION 0
|
||||
#endif
|
||||
|
||||
#if defined(MLX_PLAT_WINDOWS)
|
||||
#define VK_USE_PLATFORM_WIN32_KHR
|
||||
#ifdef __cplusplus
|
||||
constexpr const char* VULKAN_LIB_NAME = "vulkan-1.dll";
|
||||
#endif
|
||||
#elif defined(MLX_PLAT_MACOS)
|
||||
#define VK_USE_PLATFORM_MACOS_MVK
|
||||
#define VK_USE_PLATFORM_METAL_EXT
|
||||
#ifdef __cplusplus
|
||||
constexpr const char* VULKAN_LIB_NAME = "libvulkan.dylib / libvulkan.1.dylib / libMoltenVK.dylib";
|
||||
#endif
|
||||
#else
|
||||
#define VK_USE_PLATFORM_XLIB_KHR
|
||||
#define VK_USE_PLATFORM_WAYLAND_KHR
|
||||
#ifdef __cplusplus
|
||||
constexpr const char* VULKAN_LIB_NAME = "libvulkan.so / libvulkan.so.1";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Checking common assumptions
|
||||
#ifdef __cplusplus
|
||||
#include <climits>
|
||||
#include <cstdint>
|
||||
|
||||
static_assert(CHAR_BIT == 8, "CHAR_BIT is expected to be 8");
|
||||
|
||||
static_assert(sizeof(int8_t) == 1, "int8_t is not of the correct size" );
|
||||
static_assert(sizeof(int16_t) == 2, "int16_t is not of the correct size");
|
||||
static_assert(sizeof(int32_t) == 4, "int32_t is not of the correct size");
|
||||
static_assert(sizeof(int64_t) == 8, "int64_t is not of the correct size");
|
||||
|
||||
static_assert(sizeof(uint8_t) == 1, "uint8_t is not of the correct size" );
|
||||
static_assert(sizeof(uint16_t) == 2, "uint16_t is not of the correct size");
|
||||
static_assert(sizeof(uint32_t) == 4, "uint32_t is not of the correct size");
|
||||
static_assert(sizeof(uint64_t) == 8, "uint64_t is not of the correct size");
|
||||
#elif MLX_C_VERSION >= 2011
|
||||
#if MLX_C_VERSION < 2023
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static_assert(CHAR_BIT == 8, "CHAR_BIT is expected to be 8");
|
||||
|
||||
static_assert(sizeof(int8_t) == 1, "int8_t is not of the correct size" );
|
||||
static_assert(sizeof(int16_t) == 2, "int16_t is not of the correct size");
|
||||
static_assert(sizeof(int32_t) == 4, "int32_t is not of the correct size");
|
||||
static_assert(sizeof(int64_t) == 8, "int64_t is not of the correct size");
|
||||
|
||||
static_assert(sizeof(uint8_t) == 1, "uint8_t is not of the correct size" );
|
||||
static_assert(sizeof(uint16_t) == 2, "uint16_t is not of the correct size");
|
||||
static_assert(sizeof(uint32_t) == 4, "uint32_t is not of the correct size");
|
||||
static_assert(sizeof(uint64_t) == 8, "uint64_t is not of the correct size");
|
||||
#elif defined(MLX_COMPILER_GCC)
|
||||
#define STATIC_ASSERT(cnd, descr) \
|
||||
({ \
|
||||
extern int __attribute__((error("static assert failed: (" #cnd ") (" #descr ")"))) compile_time_check(void); \
|
||||
((cnd) ? 0 : compile_time_check()), 0; \
|
||||
})
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
STATIC_ASSERT(CHAR_BIT == 8, "CHAR_BIT is expected to be 8");
|
||||
|
||||
STATIC_ASSERT(sizeof(int8_t) == 1, "int8_t is not of the correct size" );
|
||||
STATIC_ASSERT(sizeof(int16_t) == 2, "int16_t is not of the correct size");
|
||||
STATIC_ASSERT(sizeof(int32_t) == 4, "int32_t is not of the correct size");
|
||||
STATIC_ASSERT(sizeof(int64_t) == 8, "int64_t is not of the correct size");
|
||||
|
||||
STATIC_ASSERT(sizeof(uint8_t) == 1, "uint8_t is not of the correct size" );
|
||||
STATIC_ASSERT(sizeof(uint16_t) == 2, "uint16_t is not of the correct size");
|
||||
STATIC_ASSERT(sizeof(uint32_t) == 4, "uint32_t is not of the correct size");
|
||||
STATIC_ASSERT(sizeof(uint64_t) == 8, "uint64_t is not of the correct size");
|
||||
#else
|
||||
#define STATIC_ASSERT(COND, MSG) typedef char static_assertion___##MSG[(COND)?1:-1]
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
STATIC_ASSERT(CHAR_BIT == 8, CHAR_BIT_is_expected_to_be_8);
|
||||
|
||||
STATIC_ASSERT(sizeof(int8_t) == 1, int8_t_is_not_of_the_correct_size);
|
||||
STATIC_ASSERT(sizeof(int16_t) == 2, int16_t_is_not_of_the_correct_size);
|
||||
STATIC_ASSERT(sizeof(int32_t) == 4, int32_t_is_not_of_the_correct_size);
|
||||
STATIC_ASSERT(sizeof(int64_t) == 8, int64_t_is_not_of_the_correct_size);
|
||||
|
||||
STATIC_ASSERT(sizeof(uint8_t) == 1, uint8_t_is_not_of_the_correct_size);
|
||||
STATIC_ASSERT(sizeof(uint16_t) == 2, uint16_t_is_not_of_the_correct_size);
|
||||
STATIC_ASSERT(sizeof(uint32_t) == 4, uint32_t_is_not_of_the_correct_size);
|
||||
STATIC_ASSERT(sizeof(uint64_t) == 8, uint64_t_is_not_of_the_correct_size);
|
||||
#endif
|
||||
|
||||
#endif
|
BIN
MacroLibX/libmlx.so
Executable file
BIN
MacroLibX/libmlx.so
Executable file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/core/application.o
Normal file
BIN
MacroLibX/objs/makefile/src/core/application.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/core/bridge.o
Normal file
BIN
MacroLibX/objs/makefile/src/core/bridge.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/core/errors.o
Normal file
BIN
MacroLibX/objs/makefile/src/core/errors.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/core/graphics.o
Normal file
BIN
MacroLibX/objs/makefile/src/core/graphics.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/core/memory.o
Normal file
BIN
MacroLibX/objs/makefile/src/core/memory.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/platform/inputs.o
Normal file
BIN
MacroLibX/objs/makefile/src/platform/inputs.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/platform/window.o
Normal file
BIN
MacroLibX/objs/makefile/src/platform/window.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/buffers/vk_buffer.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/buffers/vk_buffer.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/buffers/vk_ubo.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/buffers/vk_ubo.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/buffers/vk_vbo.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/buffers/vk_vbo.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/command/cmd_manager.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/command/cmd_manager.o
Normal file
Binary file not shown.
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/command/vk_cmd_buffer.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/command/vk_cmd_buffer.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/command/vk_cmd_pool.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/command/vk_cmd_pool.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/core/memory.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/core/memory.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/core/render_core.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/core/render_core.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/core/vk_device.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/core/vk_device.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/core/vk_fence.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/core/vk_fence.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/core/vk_instance.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/core/vk_instance.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/core/vk_queues.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/core/vk_queues.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/core/vk_semaphore.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/core/vk_semaphore.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/core/vk_surface.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/core/vk_surface.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/core/vk_validation_layers.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/core/vk_validation_layers.o
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/font.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/font.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/images/texture.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/images/texture.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/images/texture_atlas.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/images/texture_atlas.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/images/vk_image.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/images/vk_image.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/pipeline/pipeline.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/pipeline/pipeline.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/pixel_put.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/pixel_put.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/renderer.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/renderer.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/renderpass/vk_framebuffer.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/renderpass/vk_framebuffer.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/renderpass/vk_render_pass.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/renderpass/vk_render_pass.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/swapchain/vk_swapchain.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/swapchain/vk_swapchain.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/text_library.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/text_library.o
Normal file
Binary file not shown.
BIN
MacroLibX/objs/makefile/src/renderer/text_pipeline.o
Normal file
BIN
MacroLibX/objs/makefile/src/renderer/text_pipeline.o
Normal file
Binary file not shown.
BIN
MacroLibX/res/logo.png
Normal file
BIN
MacroLibX/res/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.1 KiB |
BIN
MacroLibX/res/screenshot_test.png
Normal file
BIN
MacroLibX/res/screenshot_test.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
BIN
MacroLibX/res/screenshot_test_windows.png
Normal file
BIN
MacroLibX/res/screenshot_test_windows.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
31
MacroLibX/scripts/fetch_dependencies.sh
Normal file
31
MacroLibX/scripts/fetch_dependencies.sh
Normal file
@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Update volk
|
||||
rm -f ../third_party/volk.c
|
||||
rm -f ../third_party/volk.h
|
||||
tag_name=$(curl -sL https://api.github.com/repos/zeux/Volk/releases/latest | jq -r '.tag_name')
|
||||
wget https://api.github.com/repos/zeux/volk/zipball/$tag_name -O volk.zip
|
||||
unzip -o volk.zip -d ../third_party/
|
||||
mv ../third_party/zeux-volk*/volk.h ../third_party
|
||||
mv ../third_party/zeux-volk*/volk.c ../third_party
|
||||
rm -rf ../third_party/zeux-volk*
|
||||
rm volk.zip
|
||||
|
||||
# Update VMA
|
||||
rm -f ../third_party/vma.h
|
||||
tag_name=$(curl -sL https://api.github.com/repos/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator/releases/latest | jq -r '.tag_name')
|
||||
wget https://api.github.com/repos/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator/zipball/$tag_name -O vma.zip
|
||||
unzip -o vma.zip -d ../third_party/
|
||||
mv ../third_party/GPUOpen-LibrariesAndSDKs-VulkanMemoryAllocator*/include/vk_mem_alloc.h ../third_party/vma.h
|
||||
rm -rf ../third_party/GPUOpen-LibrariesAndSDKs-VulkanMemoryAllocator*
|
||||
rm vma.zip
|
||||
|
||||
# Update Vulkan headers
|
||||
rm -rf ../third_party/vulkan
|
||||
rm -rf ../third_party/vk_video
|
||||
wget https://github.com/KhronosGroup/Vulkan-Headers/archive/main.zip -O vulkan-headers.zip
|
||||
unzip -o vulkan-headers.zip -d ../third_party/
|
||||
mv ../third_party/Vulkan-Headers-main/include/vulkan ../third_party/
|
||||
mv ../third_party/Vulkan-Headers-main/include/vk_video ../third_party/
|
||||
rm -rf ../third_party/Vulkan-Headers-main
|
||||
rm vulkan-headers.zip
|
79
MacroLibX/src/core/application.cpp
Normal file
79
MacroLibX/src/core/application.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* application.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/04 22:10:52 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/27 21:30:10 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "application.h"
|
||||
#include <SDL2/SDL.h>
|
||||
#include <renderer/images/texture.h>
|
||||
#include <renderer/core/render_core.h>
|
||||
#include <array>
|
||||
#include <core/errors.h>
|
||||
#include <mlx_profile.h>
|
||||
#include <core/memory.h>
|
||||
|
||||
namespace mlx::core
|
||||
{
|
||||
static bool __drop_sdl_responsability = false;
|
||||
Application::Application() : _in(std::make_unique<Input>())
|
||||
{
|
||||
__drop_sdl_responsability = SDL_WasInit(SDL_INIT_VIDEO);
|
||||
if(__drop_sdl_responsability) // is case the mlx is running in a sandbox like MacroUnitTester where SDL is already init
|
||||
return;
|
||||
SDL_SetMemoryFunctions(MemManager::malloc, MemManager::calloc, MemManager::realloc, MemManager::free);
|
||||
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_TIMER) != 0)
|
||||
error::report(e_kind::fatal_error, "SDL error : unable to init all subsystems : %s", SDL_GetError());
|
||||
}
|
||||
|
||||
void Application::run() noexcept
|
||||
{
|
||||
while(_in->is_running())
|
||||
{
|
||||
_in->update();
|
||||
|
||||
if(_loop_hook)
|
||||
_loop_hook(_param);
|
||||
|
||||
for(auto& gs : _graphics)
|
||||
gs->render();
|
||||
}
|
||||
}
|
||||
|
||||
void* Application::newTexture(int w, int h)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
_textures.emplace_front().create(nullptr, w, h, VK_FORMAT_R8G8B8A8_UNORM, "__mlx_unamed_user_texture");
|
||||
#else
|
||||
_textures.emplace_front().create(nullptr, w, h, VK_FORMAT_R8G8B8A8_UNORM, nullptr);
|
||||
#endif
|
||||
return &_textures.front();
|
||||
}
|
||||
|
||||
void* Application::newStbTexture(char* file, int* w, int* h)
|
||||
{
|
||||
_textures.emplace_front(stbTextureLoad(file, w, h));
|
||||
return &_textures.front();
|
||||
}
|
||||
|
||||
void Application::destroyTexture(void* ptr)
|
||||
{
|
||||
vkDeviceWaitIdle(Render_Core::get().getDevice().get()); // TODO : synchronize with another method than stopping all the GPU process
|
||||
Texture* texture = static_cast<Texture*>(ptr);
|
||||
texture->destroy();
|
||||
}
|
||||
|
||||
Application::~Application()
|
||||
{
|
||||
if(__drop_sdl_responsability)
|
||||
return;
|
||||
SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_EVENTS);
|
||||
SDL_Quit();
|
||||
}
|
||||
}
|
77
MacroLibX/src/core/application.h
Normal file
77
MacroLibX/src/core/application.h
Normal file
@ -0,0 +1,77 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* application.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/04 21:49:46 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/22 21:04:48 by kbz_8 ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_APPLICATION__
|
||||
#define __MLX_APPLICATION__
|
||||
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <functional>
|
||||
|
||||
#include <core/errors.h>
|
||||
|
||||
#include <core/graphics.h>
|
||||
#include <platform/inputs.h>
|
||||
#include <mlx_profile.h>
|
||||
|
||||
namespace mlx::core
|
||||
{
|
||||
class Application
|
||||
{
|
||||
public:
|
||||
Application();
|
||||
|
||||
inline void getMousePos(int* x, int* y) noexcept;
|
||||
inline void mouseMove(void* win, int x, int y) noexcept;
|
||||
|
||||
inline void onEvent(void* win, int event, int (*funct_ptr)(int, void*), void* param) noexcept;
|
||||
|
||||
inline void getScreenSize(int* w, int* h) noexcept;
|
||||
|
||||
inline void* newGraphicsSuport(std::size_t w, std::size_t h, const char* title);
|
||||
inline void clearGraphicsSupport(void* win);
|
||||
inline void destroyGraphicsSupport(void* win);
|
||||
|
||||
inline void pixelPut(void* win, int x, int y, uint32_t color) const noexcept;
|
||||
inline void stringPut(void* win, int x, int y, int color, char* str);
|
||||
|
||||
void* newTexture(int w, int h);
|
||||
void* newStbTexture(char* file, int* w, int* h); // stb textures are format managed by stb image (png, jpg, bpm, ...)
|
||||
inline void texturePut(void* win, void* img, int x, int y);
|
||||
inline int getTexturePixel(void* img, int x, int y);
|
||||
inline void setTexturePixel(void* img, int x, int y, uint32_t color);
|
||||
void destroyTexture(void* ptr);
|
||||
|
||||
inline void loopHook(int (*f)(void*), void* param);
|
||||
inline void loopEnd() noexcept;
|
||||
|
||||
inline void loadFont(void* win, const std::filesystem::path& filepath, float scale);
|
||||
|
||||
void run() noexcept;
|
||||
|
||||
~Application();
|
||||
|
||||
private:
|
||||
std::list<Texture> _textures;
|
||||
std::vector<std::unique_ptr<GraphicsSupport>> _graphics;
|
||||
std::function<int(void*)> _loop_hook;
|
||||
std::unique_ptr<Input> _in;
|
||||
void* _param = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
#include <core/application.inl>
|
||||
|
||||
#endif // __MLX_APPLICATION__
|
158
MacroLibX/src/core/application.inl
Normal file
158
MacroLibX/src/core/application.inl
Normal file
@ -0,0 +1,158 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* application.inl :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/04 21:49:46 by maldavid #+# #+# */
|
||||
/* Updated: 2023/04/02 14:56:27 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <core/application.h>
|
||||
|
||||
#define CHECK_WINDOW_PTR(win) \
|
||||
if(win == nullptr) \
|
||||
{ \
|
||||
core::error::report(e_kind::error, "invalid window ptr (NULL)"); \
|
||||
return; \
|
||||
} \
|
||||
else if(*static_cast<int*>(win) < 0 || *static_cast<int*>(win) > static_cast<int>(_graphics.size()))\
|
||||
{ \
|
||||
core::error::report(e_kind::error, "invalid window ptr"); \
|
||||
return; \
|
||||
} else {}\
|
||||
|
||||
namespace mlx::core
|
||||
{
|
||||
void Application::getMousePos(int* x, int* y) noexcept
|
||||
{
|
||||
*x = _in->getX();
|
||||
*y = _in->getY();
|
||||
}
|
||||
|
||||
void Application::mouseMove(void* win, int x, int y) noexcept
|
||||
{
|
||||
CHECK_WINDOW_PTR(win);
|
||||
SDL_WarpMouseInWindow(_graphics[*static_cast<int*>(win)]->getWindow()->getNativeWindow(), x, y);
|
||||
SDL_PumpEvents();
|
||||
SDL_FlushEvent(SDL_MOUSEMOTION);
|
||||
}
|
||||
|
||||
void Application::onEvent(void* win, int event, int (*funct_ptr)(int, void*), void* param) noexcept
|
||||
{
|
||||
CHECK_WINDOW_PTR(win);
|
||||
_in->onEvent(_graphics[*static_cast<int*>(win)]->getWindow()->getID(), event, funct_ptr, param);
|
||||
}
|
||||
|
||||
void Application::getScreenSize(int* w, int* h) noexcept
|
||||
{
|
||||
SDL_DisplayMode DM;
|
||||
SDL_GetDesktopDisplayMode(0, &DM);
|
||||
*w = DM.w;
|
||||
*h = DM.h;
|
||||
}
|
||||
|
||||
void* Application::newGraphicsSuport(std::size_t w, std::size_t h, const char* title)
|
||||
{
|
||||
auto it = std::find_if(_textures.begin(), _textures.end(), [=](const Texture& texture)
|
||||
{
|
||||
return &texture == reinterpret_cast<Texture*>(const_cast<char*>(title));
|
||||
});
|
||||
if(it != _textures.end())
|
||||
_graphics.emplace_back(std::make_unique<GraphicsSupport>(w, h, reinterpret_cast<Texture*>(const_cast<char*>(title)), _graphics.size()));
|
||||
else
|
||||
{
|
||||
_graphics.emplace_back(std::make_unique<GraphicsSupport>(w, h, title, _graphics.size()));
|
||||
_in->addWindow(_graphics.back()->getWindow());
|
||||
}
|
||||
return static_cast<void*>(&_graphics.back()->getID());
|
||||
}
|
||||
|
||||
void Application::clearGraphicsSupport(void* win)
|
||||
{
|
||||
CHECK_WINDOW_PTR(win);
|
||||
_graphics[*static_cast<int*>(win)]->clearRenderData();
|
||||
}
|
||||
|
||||
void Application::destroyGraphicsSupport(void* win)
|
||||
{
|
||||
CHECK_WINDOW_PTR(win);
|
||||
_graphics[*static_cast<int*>(win)].reset();
|
||||
}
|
||||
|
||||
void Application::pixelPut(void* win, int x, int y, uint32_t color) const noexcept
|
||||
{
|
||||
CHECK_WINDOW_PTR(win);
|
||||
_graphics[*static_cast<int*>(win)]->pixelPut(x, y, color);
|
||||
}
|
||||
|
||||
void Application::stringPut(void* win, int x, int y, int color, char* str)
|
||||
{
|
||||
CHECK_WINDOW_PTR(win);
|
||||
_graphics[*static_cast<int*>(win)]->stringPut(x, y, color, str);
|
||||
}
|
||||
|
||||
void Application::loadFont(void* win, const std::filesystem::path& filepath, float scale)
|
||||
{
|
||||
CHECK_WINDOW_PTR(win);
|
||||
_graphics[*static_cast<int*>(win)]->loadFont(filepath, scale);
|
||||
}
|
||||
|
||||
void Application::texturePut(void* win, void* img, int x, int y)
|
||||
{
|
||||
CHECK_WINDOW_PTR(win);
|
||||
if(img == nullptr)
|
||||
{
|
||||
core::error::report(e_kind::error, "wrong texture (NULL)");
|
||||
return;
|
||||
}
|
||||
Texture* texture = static_cast<Texture*>(img);
|
||||
if(!texture->isInit())
|
||||
core::error::report(e_kind::error, "trying to put a texture that has been destroyed");
|
||||
else
|
||||
_graphics[*static_cast<int*>(win)]->texturePut(texture, x, y);
|
||||
}
|
||||
|
||||
int Application::getTexturePixel(void* img, int x, int y)
|
||||
{
|
||||
if(img == nullptr)
|
||||
{
|
||||
core::error::report(e_kind::error, "wrong texture (NULL)");
|
||||
return 0;
|
||||
}
|
||||
Texture* texture = static_cast<Texture*>(img);
|
||||
if(!texture->isInit())
|
||||
{
|
||||
core::error::report(e_kind::error, "trying to get a pixel from texture that has been destroyed");
|
||||
return 0;
|
||||
}
|
||||
return texture->getPixel(x, y);
|
||||
}
|
||||
|
||||
void Application::setTexturePixel(void* img, int x, int y, uint32_t color)
|
||||
{
|
||||
if(img == nullptr)
|
||||
{
|
||||
core::error::report(e_kind::error, "wrong texture (NULL)");
|
||||
return;
|
||||
}
|
||||
Texture* texture = static_cast<Texture*>(img);
|
||||
if(!texture->isInit())
|
||||
core::error::report(e_kind::error, "trying to set a pixel on texture that has been destroyed");
|
||||
else
|
||||
texture->setPixel(x, y, color);
|
||||
}
|
||||
|
||||
void Application::loopHook(int (*f)(void*), void* param)
|
||||
{
|
||||
_loop_hook = f;
|
||||
_param = param;
|
||||
}
|
||||
|
||||
void Application::loopEnd() noexcept
|
||||
{
|
||||
_in->finish();
|
||||
}
|
||||
}
|
255
MacroLibX/src/core/bridge.cpp
Normal file
255
MacroLibX/src/core/bridge.cpp
Normal file
@ -0,0 +1,255 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* bridge.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/04 17:35:20 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/31 00:22:58 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include "errors.h"
|
||||
#include "application.h"
|
||||
#include <renderer/core/render_core.h>
|
||||
#include <filesystem>
|
||||
#include <mlx.h>
|
||||
#include <core/memory.h>
|
||||
#include <mlx_profile.h>
|
||||
|
||||
static void* __mlx_ptr = nullptr;
|
||||
|
||||
#define MLX_CHECK_APPLICATION_POINTER(ptr) \
|
||||
if(ptr != __mlx_ptr || ptr == NULL) \
|
||||
mlx::core::error::report(e_kind::fatal_error, "invalid mlx pointer passed to '%s'", MLX_FUNC_SIG); \
|
||||
else {} // just to avoid issues with possible if-else statements outside this macro
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void* mlx_init()
|
||||
{
|
||||
if(__mlx_ptr != nullptr)
|
||||
{
|
||||
mlx::core::error::report(e_kind::error, "MLX cannot be initialized multiple times");
|
||||
return NULL; // not nullptr for the C compatibility
|
||||
}
|
||||
mlx::MemManager::get(); // just to initialize the C garbage collector
|
||||
mlx::core::Application* app = new mlx::core::Application;
|
||||
mlx::Render_Core::get().init();
|
||||
if(app == nullptr)
|
||||
mlx::core::error::report(e_kind::fatal_error, "Tout a pété");
|
||||
__mlx_ptr = static_cast<void*>(app);
|
||||
return __mlx_ptr;
|
||||
}
|
||||
|
||||
void* mlx_new_window(void* mlx, int w, int h, const char* title)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
return static_cast<mlx::core::Application*>(mlx)->newGraphicsSuport(w, h, title);
|
||||
}
|
||||
|
||||
int mlx_loop_hook(void* mlx, int (*f)(void*), void* param)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
static_cast<mlx::core::Application*>(mlx)->loopHook(f, param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mlx_loop(void* mlx)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
static_cast<mlx::core::Application*>(mlx)->run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mlx_loop_end(void* mlx)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
static_cast<mlx::core::Application*>(mlx)->loopEnd();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mlx_mouse_show()
|
||||
{
|
||||
return SDL_ShowCursor(SDL_ENABLE);
|
||||
}
|
||||
|
||||
int mlx_mouse_hide()
|
||||
{
|
||||
return SDL_ShowCursor(SDL_DISABLE);
|
||||
}
|
||||
|
||||
int mlx_mouse_move(void* mlx, void* win, int x, int y)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
static_cast<mlx::core::Application*>(mlx)->mouseMove(win, x, y);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mlx_mouse_get_pos(void* mlx, int* x, int* y)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
static_cast<mlx::core::Application*>(mlx)->getMousePos(x, y);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mlx_on_event(void* mlx, void* win, mlx_event_type event, int (*funct_ptr)(int, void*), void* param)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
static_cast<mlx::core::Application*>(mlx)->onEvent(win, static_cast<int>(event), funct_ptr, param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* mlx_new_image(void* mlx, int width, int height)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
return static_cast<mlx::core::Application*>(mlx)->newTexture(width, height);
|
||||
}
|
||||
|
||||
int mlx_get_image_pixel(void* mlx, void* img, int x, int y)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
return static_cast<mlx::core::Application*>(mlx)->getTexturePixel(img, x, y);
|
||||
}
|
||||
|
||||
void mlx_set_image_pixel(void* mlx, void* img, int x, int y, int color)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
unsigned char color_bits[4];
|
||||
color_bits[0] = (color & 0x00FF0000) >> 16;
|
||||
color_bits[1] = (color & 0x0000FF00) >> 8;
|
||||
color_bits[2] = (color & 0x000000FF);
|
||||
color_bits[3] = (color & 0xFF000000) >> 24;
|
||||
static_cast<mlx::core::Application*>(mlx)->setTexturePixel(img, x, y, *reinterpret_cast<unsigned int*>(color_bits));
|
||||
}
|
||||
|
||||
int mlx_put_image_to_window(void* mlx, void* win, void* img, int x, int y)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
static_cast<mlx::core::Application*>(mlx)->texturePut(win, img, x, y);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mlx_destroy_image(void* mlx, void* img)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
static_cast<mlx::core::Application*>(mlx)->destroyTexture(img);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* mlx_png_file_to_image(void* mlx, char* filename, int* width, int* height)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
std::filesystem::path file(filename);
|
||||
if(file.extension() != ".png")
|
||||
{
|
||||
mlx::core::error::report(e_kind::error, "PNG loader : not a png file '%s'", filename);
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<mlx::core::Application*>(mlx)->newStbTexture(filename, width, height);
|
||||
}
|
||||
|
||||
void* mlx_jpg_file_to_image(void* mlx, char* filename, int* width, int* height)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
std::filesystem::path file(filename);
|
||||
if(file.extension() != ".jpg" && file.extension() != ".jpeg")
|
||||
{
|
||||
mlx::core::error::report(e_kind::error, "JPG loader : not a jpg file '%s'", filename);
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<mlx::core::Application*>(mlx)->newStbTexture(filename, width, height);
|
||||
}
|
||||
|
||||
void* mlx_bmp_file_to_image(void* mlx, char* filename, int* width, int* height)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
std::filesystem::path file(filename);
|
||||
if(file.extension() != ".bmp" && file.extension() != ".dib")
|
||||
{
|
||||
mlx::core::error::report(e_kind::error, "BMP loader : not a bmp file '%s'", filename);
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<mlx::core::Application*>(mlx)->newStbTexture(filename, width, height);
|
||||
}
|
||||
|
||||
int mlx_pixel_put(void* mlx, void* win, int x, int y, int color)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
unsigned char color_bits[4];
|
||||
color_bits[0] = (color & 0x00FF0000) >> 16;
|
||||
color_bits[1] = (color & 0x0000FF00) >> 8;
|
||||
color_bits[2] = (color & 0x000000FF);
|
||||
color_bits[3] = (color & 0xFF000000) >> 24;
|
||||
static_cast<mlx::core::Application*>(mlx)->pixelPut(win, x, y, *reinterpret_cast<unsigned int*>(color_bits));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mlx_string_put(void* mlx, void* win, int x, int y, int color, char* str)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
unsigned char color_bits[4];
|
||||
color_bits[0] = (color & 0x00FF0000) >> 16;
|
||||
color_bits[1] = (color & 0x0000FF00) >> 8;
|
||||
color_bits[2] = color & 0x000000FF;
|
||||
color_bits[3] = 0xFF;
|
||||
static_cast<mlx::core::Application*>(mlx)->stringPut(win, x, y, *reinterpret_cast<unsigned int*>(color_bits), str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mlx_set_font(void* mlx, void* win, char* filepath)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
std::filesystem::path file(filepath);
|
||||
if(std::strcmp(filepath, "default") != 0 && file.extension() != ".ttf" && file.extension() != ".tte")
|
||||
{
|
||||
mlx::core::error::report(e_kind::error, "TTF loader : not a truetype font file '%s'", filepath);
|
||||
return;
|
||||
}
|
||||
static_cast<mlx::core::Application*>(mlx)->loadFont(win, file, 16.f);
|
||||
}
|
||||
|
||||
void mlx_set_font_scale(void* mlx, void* win, char* filepath, float scale)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
std::filesystem::path file(filepath);
|
||||
if(std::strcmp(filepath, "default") != 0 && file.extension() != ".ttf" && file.extension() != ".tte")
|
||||
{
|
||||
mlx::core::error::report(e_kind::error, "TTF loader : not a truetype font file '%s'", filepath);
|
||||
return;
|
||||
}
|
||||
static_cast<mlx::core::Application*>(mlx)->loadFont(win, file, scale);
|
||||
}
|
||||
|
||||
int mlx_clear_window(void* mlx, void* win)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
static_cast<mlx::core::Application*>(mlx)->clearGraphicsSupport(win);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mlx_destroy_window(void* mlx, void* win)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
static_cast<mlx::core::Application*>(mlx)->destroyGraphicsSupport(win);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mlx_destroy_display(void* mlx)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
delete static_cast<mlx::core::Application*>(mlx);
|
||||
mlx::Render_Core::get().destroy();
|
||||
__mlx_ptr = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mlx_get_screens_size(void* mlx, int* w, int* h)
|
||||
{
|
||||
MLX_CHECK_APPLICATION_POINTER(mlx);
|
||||
static_cast<mlx::core::Application*>(mlx)->getScreenSize(w, h);
|
||||
return 0;
|
||||
}
|
||||
}
|
44
MacroLibX/src/core/errors.cpp
Normal file
44
MacroLibX/src/core/errors.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* errors.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/04 17:48:06 by maldavid #+# #+# */
|
||||
/* Updated: 2023/11/14 07:14:57 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <cstdarg>
|
||||
#include <utility>
|
||||
|
||||
#include "errors.h"
|
||||
|
||||
constexpr const int BUFFER_SIZE = 4096;
|
||||
|
||||
namespace mlx::core::error
|
||||
{
|
||||
void report(e_kind kind, std::string msg, ...)
|
||||
{
|
||||
char buffer[BUFFER_SIZE];
|
||||
|
||||
va_list al;
|
||||
va_start(al, msg);
|
||||
std::vsnprintf(buffer, BUFFER_SIZE, msg.c_str(), al);
|
||||
va_end(al);
|
||||
|
||||
switch(kind)
|
||||
{
|
||||
case e_kind::message: std::cout << "\033[1;34m[MacroLibX] Message : \033[1;0m" << buffer << std::endl; break;
|
||||
case e_kind::warning: std::cout << "\033[1;35m[MacroLibX] Warning : \033[1;0m" << buffer << std::endl; break;
|
||||
case e_kind::error: std::cerr << "\033[1;31m[MacroLibX] Error : \033[1;0m" << buffer << std::endl; break;
|
||||
case e_kind::fatal_error:
|
||||
std::cerr << "\033[1;31m[MacroLibX] Fatal Error : \033[1;0m" << buffer << std::endl;
|
||||
std::exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
32
MacroLibX/src/core/errors.h
Normal file
32
MacroLibX/src/core/errors.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* errors.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/04 17:42:32 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/27 17:21:07 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_ERRORS__
|
||||
#define __MLX_ERRORS__
|
||||
|
||||
#include <string>
|
||||
#include <mlx_profile.h>
|
||||
|
||||
enum class e_kind
|
||||
{
|
||||
message,
|
||||
warning,
|
||||
error,
|
||||
fatal_error
|
||||
};
|
||||
|
||||
namespace mlx::core::error
|
||||
{
|
||||
void report(e_kind kind, std::string msg, ...);
|
||||
}
|
||||
|
||||
#endif // __MLX_ERRORS__
|
104
MacroLibX/src/core/graphics.cpp
Normal file
104
MacroLibX/src/core/graphics.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* graphics.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/04/02 15:13:55 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/27 21:27:48 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <core/graphics.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
GraphicsSupport::GraphicsSupport(std::size_t w, std::size_t h, Texture* render_target, int id) :
|
||||
_window(nullptr),
|
||||
_text_put_pipeline(std::make_unique<TextPutPipeline>()),
|
||||
_renderer(std::make_unique<Renderer>()),
|
||||
_width(w),
|
||||
_height(h),
|
||||
_id(id)
|
||||
{
|
||||
_renderer->setWindow(nullptr);
|
||||
_renderer->init(render_target);
|
||||
_pixel_put_pipeline.init(w, h, *_renderer);
|
||||
_text_put_pipeline->init(_renderer.get());
|
||||
}
|
||||
|
||||
GraphicsSupport::GraphicsSupport(std::size_t w, std::size_t h, std::string title, int id) :
|
||||
_window(std::make_shared<MLX_Window>(w, h, title)),
|
||||
_text_put_pipeline(std::make_unique<TextPutPipeline>()),
|
||||
_renderer(std::make_unique<Renderer>()),
|
||||
_width(w),
|
||||
_height(h),
|
||||
_id(id)
|
||||
{
|
||||
_renderer->setWindow(_window.get());
|
||||
_renderer->init(nullptr);
|
||||
_pixel_put_pipeline.init(w, h, *_renderer);
|
||||
_text_put_pipeline->init(_renderer.get());
|
||||
}
|
||||
|
||||
void GraphicsSupport::render() noexcept
|
||||
{
|
||||
if(!_renderer->beginFrame())
|
||||
return;
|
||||
_proj = glm::ortho<float>(0, _width, 0, _height);
|
||||
_renderer->getUniformBuffer()->setData(sizeof(_proj), &_proj);
|
||||
auto cmd_buff = _renderer->getActiveCmdBuffer().get();
|
||||
|
||||
static std::array<VkDescriptorSet, 2> sets = {
|
||||
_renderer->getVertDescriptorSet().get(),
|
||||
VK_NULL_HANDLE
|
||||
};
|
||||
|
||||
for(auto& data : _textures_to_render)
|
||||
{
|
||||
if(!data.texture->isInit())
|
||||
continue;
|
||||
if(data.texture->getSet() == VK_NULL_HANDLE)
|
||||
data.texture->setDescriptor(_renderer->getFragDescriptorSet().duplicate());
|
||||
if(data.texture->getLayout() != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
|
||||
data.texture->transitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
if(!data.texture->hasBeenUpdated())
|
||||
data.texture->updateSet(0);
|
||||
sets[1] = data.texture->getSet();
|
||||
vkCmdBindDescriptorSets(cmd_buff, VK_PIPELINE_BIND_POINT_GRAPHICS, _renderer->getPipeline().getPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr);
|
||||
data.texture->render(*_renderer, data.x, data.y);
|
||||
}
|
||||
|
||||
_pixel_put_pipeline.present();
|
||||
|
||||
sets[1] = _pixel_put_pipeline.getDescriptorSet();
|
||||
vkCmdBindDescriptorSets(cmd_buff, VK_PIPELINE_BIND_POINT_GRAPHICS, _renderer->getPipeline().getPipelineLayout(), 0, sets.size(), sets.data(), 0, nullptr);
|
||||
_pixel_put_pipeline.render(*_renderer);
|
||||
_text_put_pipeline->render(sets);
|
||||
_renderer->endFrame();
|
||||
|
||||
for(auto& data : _textures_to_render)
|
||||
data.texture->resetUpdate();
|
||||
|
||||
#ifdef GRAPHICS_MEMORY_DUMP
|
||||
// dump memory to file every two seconds
|
||||
static uint64_t timer = SDL_GetTicks64();
|
||||
if(SDL_GetTicks64() - timer > 2000)
|
||||
{
|
||||
Render_Core::get().getAllocator().dumpMemoryToJson();
|
||||
timer += 2000;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
GraphicsSupport::~GraphicsSupport()
|
||||
{
|
||||
vkDeviceWaitIdle(Render_Core::get().getDevice().get());
|
||||
_text_put_pipeline->destroy();
|
||||
_pixel_put_pipeline.destroy();
|
||||
_renderer->destroy();
|
||||
if(_window)
|
||||
_window->destroy();
|
||||
}
|
||||
}
|
67
MacroLibX/src/core/graphics.h
Normal file
67
MacroLibX/src/core/graphics.h
Normal file
@ -0,0 +1,67 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* graphics.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/04/02 14:49:49 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/24 08:56:14 by kbz_8 ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_GRAPHICS__
|
||||
#define __MLX_GRAPHICS__
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_set>
|
||||
#include <filesystem>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include <platform/window.h>
|
||||
#include <renderer/renderer.h>
|
||||
#include <renderer/pixel_put.h>
|
||||
#include <renderer/text_pipeline.h>
|
||||
#include <utils/non_copyable.h>
|
||||
#include <renderer/images/texture.h>
|
||||
#include <mlx_profile.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
class GraphicsSupport : public non_copyable
|
||||
{
|
||||
public:
|
||||
GraphicsSupport(std::size_t w, std::size_t h, Texture* render_target, int id);
|
||||
GraphicsSupport(std::size_t w, std::size_t h, std::string title, int id);
|
||||
|
||||
inline int& getID() noexcept;
|
||||
inline std::shared_ptr<MLX_Window> getWindow();
|
||||
|
||||
void render() noexcept;
|
||||
|
||||
inline void clearRenderData() noexcept;
|
||||
inline void pixelPut(int x, int y, uint32_t color) noexcept;
|
||||
inline void stringPut(int x, int y, int color, std::string str);
|
||||
inline void texturePut(Texture* texture, int x, int y);
|
||||
inline void loadFont(const std::filesystem::path& filepath, float scale);
|
||||
|
||||
~GraphicsSupport();
|
||||
|
||||
private:
|
||||
std::vector<TextureRenderData> _textures_to_render;
|
||||
PixelPutPipeline _pixel_put_pipeline;
|
||||
glm::mat4 _proj = glm::mat4(1.0);
|
||||
std::shared_ptr<MLX_Window> _window;
|
||||
std::unique_ptr<TextPutPipeline> _text_put_pipeline; // unique_ptr because of the size of the class
|
||||
std::unique_ptr<Renderer> _renderer;
|
||||
std::size_t _width = 0;
|
||||
std::size_t _height = 0;
|
||||
int _id;
|
||||
};
|
||||
}
|
||||
|
||||
#include <core/graphics.inl>
|
||||
|
||||
#endif
|
50
MacroLibX/src/core/graphics.inl
Normal file
50
MacroLibX/src/core/graphics.inl
Normal file
@ -0,0 +1,50 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* graphics.inl :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/04/02 15:13:55 by maldavid #+# #+# */
|
||||
/* Updated: 2023/04/02 15:26:16 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <core/graphics.h>
|
||||
#include <type_traits>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
int& GraphicsSupport::getID() noexcept { return _id; }
|
||||
std::shared_ptr<MLX_Window> GraphicsSupport::getWindow() { return _window; }
|
||||
|
||||
void GraphicsSupport::clearRenderData() noexcept
|
||||
{
|
||||
_textures_to_render.clear();
|
||||
_pixel_put_pipeline.clear();
|
||||
_text_put_pipeline->clear();
|
||||
}
|
||||
|
||||
void GraphicsSupport::pixelPut(int x, int y, uint32_t color) noexcept
|
||||
{
|
||||
_pixel_put_pipeline.setPixel(x, y, color);
|
||||
}
|
||||
|
||||
void GraphicsSupport::stringPut(int x, int y, int color, std::string str)
|
||||
{
|
||||
_text_put_pipeline->put(x, y, color, str);
|
||||
}
|
||||
|
||||
void GraphicsSupport::texturePut(Texture* texture, int x, int y)
|
||||
{
|
||||
_textures_to_render.emplace_back(texture, x, y);
|
||||
auto it = std::find(_textures_to_render.begin(), _textures_to_render.end() - 1, _textures_to_render.back());
|
||||
if(it != _textures_to_render.end() - 1)
|
||||
_textures_to_render.erase(it);
|
||||
}
|
||||
|
||||
void GraphicsSupport::loadFont(const std::filesystem::path& filepath, float scale)
|
||||
{
|
||||
_text_put_pipeline->loadFont(filepath, scale);
|
||||
}
|
||||
}
|
66
MacroLibX/src/core/memory.cpp
Normal file
66
MacroLibX/src/core/memory.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* memory.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/12/07 16:32:01 by kbz_8 #+# #+# */
|
||||
/* Updated: 2023/12/11 15:25:02 by kbz_8 ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <core/memory.h>
|
||||
#include <core/errors.h>
|
||||
#include <algorithm>
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
void* MemManager::malloc(std::size_t size)
|
||||
{
|
||||
void* ptr = std::malloc(size);
|
||||
if(ptr != nullptr)
|
||||
_blocks.push_back(ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* MemManager::calloc(std::size_t n, std::size_t size)
|
||||
{
|
||||
void* ptr = std::calloc(n, size);
|
||||
if(ptr != nullptr)
|
||||
_blocks.push_back(ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* MemManager::realloc(void* ptr, std::size_t size)
|
||||
{
|
||||
void* ptr2 = std::realloc(ptr, size);
|
||||
if(ptr2 != nullptr)
|
||||
_blocks.push_back(ptr2);
|
||||
auto it = std::find(_blocks.begin(), _blocks.end(), ptr);
|
||||
if(it != _blocks.end())
|
||||
_blocks.erase(it);
|
||||
return ptr2;
|
||||
}
|
||||
|
||||
void MemManager::free(void* ptr)
|
||||
{
|
||||
auto it = std::find(_blocks.begin(), _blocks.end(), ptr);
|
||||
if(it == _blocks.end())
|
||||
{
|
||||
core::error::report(e_kind::error, "Memory Manager : trying to free a pointer not allocated by the memory manager");
|
||||
return;
|
||||
}
|
||||
std::free(*it);
|
||||
_blocks.erase(it);
|
||||
}
|
||||
|
||||
MemManager::~MemManager()
|
||||
{
|
||||
std::for_each(_blocks.begin(), _blocks.end(), [](void* ptr)
|
||||
{
|
||||
std::free(ptr);
|
||||
});
|
||||
}
|
||||
}
|
41
MacroLibX/src/core/memory.h
Normal file
41
MacroLibX/src/core/memory.h
Normal file
@ -0,0 +1,41 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* memory.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/12/07 16:31:51 by kbz_8 #+# #+# */
|
||||
/* Updated: 2023/12/11 19:47:13 by kbz_8 ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_MEMORY__
|
||||
#define __MLX_MEMORY__
|
||||
|
||||
#include <utils/singleton.h>
|
||||
#include <mlx_profile.h>
|
||||
#include <list>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
class MemManager : public Singleton<MemManager>
|
||||
{
|
||||
friend class Singleton<MemManager>;
|
||||
|
||||
public:
|
||||
static void* malloc(std::size_t size);
|
||||
static void* calloc(std::size_t n, std::size_t size);
|
||||
static void* realloc(void* ptr, std::size_t size);
|
||||
static void free(void* ptr);
|
||||
|
||||
private:
|
||||
MemManager() = default;
|
||||
~MemManager();
|
||||
|
||||
private:
|
||||
inline static std::list<void*> _blocks;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
150
MacroLibX/src/platform/inputs.cpp
Normal file
150
MacroLibX/src/platform/inputs.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* inputs.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/05 16:30:19 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/11 19:01:14 by kbz_8 ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "inputs.h"
|
||||
#include <mlx.h>
|
||||
#include <cstring>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
void Input::update()
|
||||
{
|
||||
_xRel = 0;
|
||||
_yRel = 0;
|
||||
|
||||
while(SDL_PollEvent(&_event))
|
||||
{
|
||||
if(_event.type == SDL_MOUSEMOTION)
|
||||
{
|
||||
_x = _event.motion.x;
|
||||
_y = _event.motion.y;
|
||||
|
||||
_xRel = _event.motion.xrel;
|
||||
_yRel = _event.motion.yrel;
|
||||
}
|
||||
|
||||
uint32_t id = _event.window.windowID;
|
||||
if(!_events_hooks.count(id))
|
||||
continue;
|
||||
auto& hooks = _events_hooks[id];
|
||||
|
||||
switch(_event.type)
|
||||
{
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
if(hooks[MLX_KEYDOWN].hook)
|
||||
hooks[MLX_KEYDOWN].hook(_event.key.keysym.scancode, hooks[MLX_KEYDOWN].param);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_KEYUP:
|
||||
{
|
||||
if(hooks[MLX_KEYUP].hook)
|
||||
hooks[MLX_KEYUP].hook(_event.key.keysym.scancode, hooks[MLX_KEYUP].param);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
{
|
||||
if(hooks[MLX_MOUSEDOWN].hook)
|
||||
hooks[MLX_MOUSEDOWN].hook(_event.button.button, hooks[MLX_MOUSEDOWN].param);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
{
|
||||
if(hooks[MLX_MOUSEUP].hook)
|
||||
hooks[MLX_MOUSEUP].hook(_event.button.button, hooks[MLX_MOUSEUP].param);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_MOUSEWHEEL:
|
||||
{
|
||||
if(hooks[MLX_MOUSEWHEEL].hook)
|
||||
{
|
||||
if(_event.wheel.y > 0) // scroll up
|
||||
hooks[MLX_MOUSEWHEEL].hook(1, hooks[MLX_MOUSEWHEEL].param);
|
||||
else if(_event.wheel.y < 0) // scroll down
|
||||
hooks[MLX_MOUSEWHEEL].hook(2, hooks[MLX_MOUSEWHEEL].param);
|
||||
|
||||
if(_event.wheel.x > 0) // scroll right
|
||||
hooks[MLX_MOUSEWHEEL].hook(3, hooks[MLX_MOUSEWHEEL].param);
|
||||
else if(_event.wheel.x < 0) // scroll left
|
||||
hooks[MLX_MOUSEWHEEL].hook(4, hooks[MLX_MOUSEWHEEL].param);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_WINDOWEVENT:
|
||||
{
|
||||
auto& win_hook = hooks[MLX_WINDOW_EVENT];
|
||||
switch(_event.window.event)
|
||||
{
|
||||
case SDL_WINDOWEVENT_CLOSE:
|
||||
{
|
||||
if(win_hook.hook)
|
||||
win_hook.hook(0, win_hook.param);
|
||||
break;
|
||||
}
|
||||
case SDL_WINDOWEVENT_MOVED:
|
||||
{
|
||||
if(win_hook.hook)
|
||||
win_hook.hook(1, win_hook.param);
|
||||
break;
|
||||
}
|
||||
case SDL_WINDOWEVENT_MINIMIZED:
|
||||
{
|
||||
if(win_hook.hook)
|
||||
win_hook.hook(2, win_hook.param);
|
||||
break;
|
||||
}
|
||||
case SDL_WINDOWEVENT_MAXIMIZED:
|
||||
{
|
||||
if(win_hook.hook)
|
||||
win_hook.hook(3, win_hook.param);
|
||||
break;
|
||||
}
|
||||
case SDL_WINDOWEVENT_ENTER:
|
||||
{
|
||||
if(win_hook.hook)
|
||||
win_hook.hook(4, win_hook.param);
|
||||
break;
|
||||
}
|
||||
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
||||
{
|
||||
if(win_hook.hook)
|
||||
win_hook.hook(4, win_hook.param);
|
||||
break;
|
||||
}
|
||||
case SDL_WINDOWEVENT_LEAVE:
|
||||
{
|
||||
if(win_hook.hook)
|
||||
win_hook.hook(5, win_hook.param);
|
||||
break;
|
||||
}
|
||||
case SDL_WINDOWEVENT_FOCUS_LOST:
|
||||
{
|
||||
if(win_hook.hook)
|
||||
win_hook.hook(4, win_hook.param);
|
||||
break;
|
||||
}
|
||||
|
||||
default : break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
77
MacroLibX/src/platform/inputs.h
Normal file
77
MacroLibX/src/platform/inputs.h
Normal file
@ -0,0 +1,77 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* inputs.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/05 16:27:35 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/11 19:47:20 by kbz_8 ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <mlx_profile.h>
|
||||
|
||||
#include "window.h"
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
struct Hook
|
||||
{
|
||||
std::function<int(int, void*)> hook;
|
||||
void* param = nullptr;
|
||||
};
|
||||
|
||||
class Input
|
||||
{
|
||||
public:
|
||||
Input() = default;
|
||||
|
||||
void update();
|
||||
|
||||
inline bool isMouseMoving() const noexcept { return _xRel || _yRel; }
|
||||
|
||||
inline int getX() const noexcept { return _x; }
|
||||
inline int getY() const noexcept { return _y; }
|
||||
|
||||
inline int getXRel() const noexcept { return _xRel; }
|
||||
inline int getYRel() const noexcept { return _yRel; }
|
||||
|
||||
inline bool is_running() const noexcept { return !_end; }
|
||||
inline constexpr void finish() noexcept { _end = true; }
|
||||
|
||||
inline void addWindow(std::shared_ptr<MLX_Window> window)
|
||||
{
|
||||
_windows[window->getID()] = window;
|
||||
_events_hooks[window->getID()] = {};
|
||||
}
|
||||
|
||||
inline void onEvent(uint32_t id, int event, int (*funct_ptr)(int, void*), void* param) noexcept
|
||||
{
|
||||
_events_hooks[id][event].hook = funct_ptr;
|
||||
_events_hooks[id][event].param = param;
|
||||
}
|
||||
|
||||
~Input() = default;
|
||||
|
||||
private:
|
||||
std::unordered_map<uint32_t, std::shared_ptr<MLX_Window>> _windows;
|
||||
std::unordered_map<uint32_t, std::array<Hook, 6>> _events_hooks;
|
||||
SDL_Event _event;
|
||||
|
||||
int _x = 0;
|
||||
int _y = 0;
|
||||
int _xRel = 0;
|
||||
int _yRel = 0;
|
||||
|
||||
bool _end = false;
|
||||
};
|
||||
}
|
57
MacroLibX/src/platform/window.cpp
Normal file
57
MacroLibX/src/platform/window.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* window.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/04 17:36:44 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/27 16:57:28 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <platform/window.h>
|
||||
#include <core/errors.h>
|
||||
#include <utils/icon_mlx.h>
|
||||
#include <iostream>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
constexpr const uint32_t rmask = 0xff000000;
|
||||
constexpr const uint32_t gmask = 0x00ff0000;
|
||||
constexpr const uint32_t bmask = 0x0000ff00;
|
||||
constexpr const uint32_t amask = 0x000000ff;
|
||||
#else
|
||||
constexpr const uint32_t rmask = 0x000000ff;
|
||||
constexpr const uint32_t gmask = 0x0000ff00;
|
||||
constexpr const uint32_t bmask = 0x00ff0000;
|
||||
constexpr const uint32_t amask = 0xff000000;
|
||||
#endif
|
||||
|
||||
MLX_Window::MLX_Window(std::size_t w, std::size_t h, const std::string& title) : _width(w), _height(h)
|
||||
{
|
||||
if(title.find("vvaas") != std::string::npos)
|
||||
core::error::report(e_kind::message, "vvaas est mauvais");
|
||||
_win = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, w, h, SDL_WINDOW_VULKAN | SDL_WINDOW_SHOWN);
|
||||
if(!_win)
|
||||
core::error::report(e_kind::fatal_error, std::string("unable to open a new window, ") + SDL_GetError());
|
||||
_id = SDL_GetWindowID(_win);
|
||||
_icon = SDL_CreateRGBSurfaceFrom(static_cast<void*>(logo_mlx), logo_mlx_width, logo_mlx_height, 32, 4 * logo_mlx_width, rmask, gmask, bmask, amask);
|
||||
SDL_SetWindowIcon(_win, _icon);
|
||||
}
|
||||
|
||||
void MLX_Window::destroy() noexcept
|
||||
{
|
||||
if(_win != nullptr)
|
||||
{
|
||||
SDL_DestroyWindow(_win);
|
||||
_win = nullptr;
|
||||
}
|
||||
if(_icon != nullptr)
|
||||
{
|
||||
SDL_FreeSurface(_icon);
|
||||
_icon = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
45
MacroLibX/src/platform/window.h
Normal file
45
MacroLibX/src/platform/window.h
Normal file
@ -0,0 +1,45 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* window.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/04 21:53:12 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/21 00:24:26 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_WINDOW__
|
||||
#define __MLX_WINDOW__
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <string>
|
||||
#include <mlx_profile.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
class MLX_Window
|
||||
{
|
||||
public:
|
||||
MLX_Window(std::size_t w, std::size_t h, const std::string& title);
|
||||
|
||||
inline SDL_Window* getNativeWindow() const noexcept { return _win; }
|
||||
inline int getWidth() const noexcept { return _width; }
|
||||
inline int getHeight() const noexcept { return _height; }
|
||||
inline uint32_t getID() const noexcept { return _id; }
|
||||
|
||||
void destroy() noexcept;
|
||||
|
||||
~MLX_Window() = default;
|
||||
|
||||
private:
|
||||
SDL_Surface* _icon = nullptr;
|
||||
SDL_Window* _win = nullptr;
|
||||
int _width = 0;
|
||||
int _height = 0;
|
||||
uint32_t _id = -1;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
159
MacroLibX/src/renderer/buffers/vk_buffer.cpp
Normal file
159
MacroLibX/src/renderer/buffers/vk_buffer.cpp
Normal file
@ -0,0 +1,159 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* vk_buffer.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/08 18:55:57 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/16 17:10:17 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "vk_buffer.h"
|
||||
#include <renderer/command/vk_cmd_pool.h>
|
||||
#include <renderer/command/vk_cmd_buffer.h>
|
||||
#include <renderer/core/render_core.h>
|
||||
#include <vma.h>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
void Buffer::create(Buffer::kind type, VkDeviceSize size, VkBufferUsageFlags usage, const char* name, const void* data)
|
||||
{
|
||||
_usage = usage;
|
||||
if(type == Buffer::kind::constant || type == Buffer::kind::dynamic_device_local)
|
||||
{
|
||||
if(data == nullptr && type == Buffer::kind::constant)
|
||||
{
|
||||
core::error::report(e_kind::warning, "Vulkan : trying to create constant buffer without data (constant buffers cannot be modified after creation)");
|
||||
return;
|
||||
}
|
||||
_usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||
}
|
||||
|
||||
VmaAllocationCreateInfo alloc_info{};
|
||||
alloc_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
|
||||
alloc_info.usage = VMA_MEMORY_USAGE_AUTO;
|
||||
|
||||
createBuffer(_usage, alloc_info, size, name);
|
||||
|
||||
if(data != nullptr)
|
||||
{
|
||||
void* mapped = nullptr;
|
||||
mapMem(&mapped);
|
||||
std::memcpy(mapped, data, size);
|
||||
unmapMem();
|
||||
if(type == Buffer::kind::constant || type == Buffer::kind::dynamic_device_local)
|
||||
pushToGPU();
|
||||
}
|
||||
}
|
||||
|
||||
void Buffer::destroy() noexcept
|
||||
{
|
||||
if(_is_mapped)
|
||||
unmapMem();
|
||||
if(_buffer != VK_NULL_HANDLE)
|
||||
Render_Core::get().getAllocator().destroyBuffer(_allocation, _buffer);
|
||||
_buffer = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
void Buffer::createBuffer(VkBufferUsageFlags usage, VmaAllocationCreateInfo info, VkDeviceSize size, [[maybe_unused]] const char* name)
|
||||
{
|
||||
VkBufferCreateInfo bufferInfo{};
|
||||
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
bufferInfo.size = size;
|
||||
bufferInfo.usage = usage;
|
||||
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
|
||||
#ifdef DEBUG
|
||||
_name = name;
|
||||
std::string alloc_name = _name;
|
||||
if(usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT)
|
||||
alloc_name.append("_index_buffer");
|
||||
else if(usage & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT)
|
||||
alloc_name.append("_vertex_buffer");
|
||||
else if(!(usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT))
|
||||
alloc_name.append("_buffer");
|
||||
_allocation = Render_Core::get().getAllocator().createBuffer(&bufferInfo, &info, _buffer, alloc_name.c_str());
|
||||
#else
|
||||
_allocation = Render_Core::get().getAllocator().createBuffer(&bufferInfo, &info, _buffer, nullptr);
|
||||
#endif
|
||||
_size = size;
|
||||
}
|
||||
|
||||
bool Buffer::copyFromBuffer(const Buffer& buffer) noexcept
|
||||
{
|
||||
if(!(_usage & VK_BUFFER_USAGE_TRANSFER_DST_BIT))
|
||||
{
|
||||
core::error::report(e_kind::error, "Vulkan : buffer cannot be the destination of a copy because it does not have the correct usage flag");
|
||||
return false;
|
||||
}
|
||||
if(!(buffer._usage & VK_BUFFER_USAGE_TRANSFER_SRC_BIT))
|
||||
{
|
||||
core::error::report(e_kind::error, "Vulkan : buffer cannot be the source of a copy because it does not have the correct usage flag");
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO, use global cmd buffer pool to manage resources
|
||||
CmdBuffer& cmd = Render_Core::get().getSingleTimeCmdBuffer();
|
||||
cmd.beginRecord();
|
||||
|
||||
VkBufferCopy copyRegion{};
|
||||
copyRegion.size = _size;
|
||||
vkCmdCopyBuffer(cmd.get(), buffer._buffer, _buffer, 1, ©Region);
|
||||
|
||||
cmd.endRecord();
|
||||
cmd.submitIdle();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Buffer::pushToGPU() noexcept
|
||||
{
|
||||
VmaAllocationCreateInfo alloc_info{};
|
||||
alloc_info.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
|
||||
|
||||
Buffer newBuffer;
|
||||
newBuffer._usage = (_usage & 0xFFFFFFFC) | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
#ifdef DEBUG
|
||||
std::string new_name = _name + "_GPU";
|
||||
newBuffer.createBuffer(newBuffer._usage, alloc_info, _size, new_name.c_str());
|
||||
#else
|
||||
newBuffer.createBuffer(newBuffer._usage, alloc_info, _size, nullptr);
|
||||
#endif
|
||||
|
||||
if(newBuffer.copyFromBuffer(*this)) // if the copy succeded we swap the buffers, else the new one is deleted
|
||||
this->swap(newBuffer);
|
||||
newBuffer.destroy();
|
||||
}
|
||||
|
||||
void Buffer::swap(Buffer& buffer) noexcept
|
||||
{
|
||||
VkBuffer temp_b = _buffer;
|
||||
_buffer = buffer._buffer;
|
||||
buffer._buffer = temp_b;
|
||||
|
||||
VmaAllocation temp_a = buffer._allocation;
|
||||
buffer._allocation = _allocation;
|
||||
_allocation = temp_a;
|
||||
|
||||
VkDeviceSize temp_size = buffer._size;
|
||||
buffer._size = _size;
|
||||
_size = temp_size;
|
||||
|
||||
VkDeviceSize temp_offset = buffer._offset;
|
||||
buffer._offset = _offset;
|
||||
_offset = temp_offset;
|
||||
|
||||
VkBufferUsageFlags temp_u = _usage;
|
||||
_usage = buffer._usage;
|
||||
buffer._usage = temp_u;
|
||||
}
|
||||
|
||||
void Buffer::flush(VkDeviceSize size, VkDeviceSize offset)
|
||||
{
|
||||
Render_Core::get().getAllocator().flush(_allocation, size, offset);
|
||||
}
|
||||
}
|
64
MacroLibX/src/renderer/buffers/vk_buffer.h
Normal file
64
MacroLibX/src/renderer/buffers/vk_buffer.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* vk_buffer.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/06 23:18:52 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/03 15:26:56 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_VK_BUFFER__
|
||||
#define __MLX_VK_BUFFER__
|
||||
|
||||
#include <mlx_profile.h>
|
||||
#include <volk.h>
|
||||
#include <renderer/core/render_core.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
class Buffer
|
||||
{
|
||||
public:
|
||||
enum class kind { dynamic, dynamic_device_local, uniform, constant };
|
||||
|
||||
void create(kind type, VkDeviceSize size, VkBufferUsageFlags usage, const char* name, const void* data = nullptr);
|
||||
void destroy() noexcept;
|
||||
|
||||
inline void mapMem(void** data) noexcept { Render_Core::get().getAllocator().mapMemory(_allocation, data); _is_mapped = true; }
|
||||
inline bool isMapped() const noexcept { return _is_mapped; }
|
||||
inline void unmapMem() noexcept { Render_Core::get().getAllocator().unmapMemory(_allocation); _is_mapped = false; }
|
||||
|
||||
void flush(VkDeviceSize size = VK_WHOLE_SIZE, VkDeviceSize offset = 0);
|
||||
bool copyFromBuffer(const Buffer& buffer) noexcept;
|
||||
|
||||
inline VkBuffer& operator()() noexcept { return _buffer; }
|
||||
inline VkBuffer& get() noexcept { return _buffer; }
|
||||
inline VkDeviceSize getSize() const noexcept { return _size; }
|
||||
inline VkDeviceSize getOffset() const noexcept { return _offset; }
|
||||
|
||||
protected:
|
||||
void pushToGPU() noexcept;
|
||||
void swap(Buffer& buffer) noexcept;
|
||||
|
||||
protected:
|
||||
VmaAllocation _allocation;
|
||||
VkBuffer _buffer = VK_NULL_HANDLE;
|
||||
VkDeviceSize _offset = 0;
|
||||
VkDeviceSize _size = 0;
|
||||
|
||||
private:
|
||||
void createBuffer(VkBufferUsageFlags usage, VmaAllocationCreateInfo info, VkDeviceSize size, const char* name);
|
||||
|
||||
private:
|
||||
#ifdef DEBUG
|
||||
std::string _name;
|
||||
#endif
|
||||
VkBufferUsageFlags _usage = 0;
|
||||
bool _is_mapped = false;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
31
MacroLibX/src/renderer/buffers/vk_ibo.h
Normal file
31
MacroLibX/src/renderer/buffers/vk_ibo.h
Normal file
@ -0,0 +1,31 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* vk_ibo.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/01/25 15:05:05 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/03 15:27:02 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __VK_IBO__
|
||||
#define __VK_IBO__
|
||||
|
||||
#include <mlx_profile.h>
|
||||
#include <volk.h>
|
||||
#include "vk_buffer.h"
|
||||
#include <renderer/renderer.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
class C_IBO : public Buffer
|
||||
{
|
||||
public:
|
||||
inline void create(uint32_t size, const uint16_t* data, const char* name) { Buffer::create(Buffer::kind::constant, size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, name, data); }
|
||||
inline void bind(Renderer& renderer) noexcept { vkCmdBindIndexBuffer(renderer.getActiveCmdBuffer().get(), _buffer, _offset, VK_INDEX_TYPE_UINT16); }
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
74
MacroLibX/src/renderer/buffers/vk_ubo.cpp
Normal file
74
MacroLibX/src/renderer/buffers/vk_ubo.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* vk_ubo.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/06 18:45:52 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/10 22:22:28 by kbz_8 ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "vk_ubo.h"
|
||||
#include <cstring>
|
||||
#include <renderer/renderer.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
void UBO::create(Renderer* renderer, uint32_t size, [[maybe_unused]] const char* name)
|
||||
{
|
||||
_renderer = renderer;
|
||||
|
||||
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::string name_frame = name;
|
||||
name_frame.append(std::to_string(i));
|
||||
_buffers[i].create(Buffer::kind::uniform, size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, name_frame.c_str());
|
||||
#else
|
||||
_buffers[i].create(Buffer::kind::uniform, size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, nullptr);
|
||||
#endif
|
||||
_buffers[i].mapMem(&_maps[i]);
|
||||
if(_maps[i] == nullptr)
|
||||
core::error::report(e_kind::fatal_error, "Vulkan : unable to map a uniform buffer");
|
||||
}
|
||||
}
|
||||
|
||||
void UBO::setData(uint32_t size, const void* data)
|
||||
{
|
||||
std::memcpy(_maps[_renderer->getActiveImageIndex()], data, static_cast<size_t>(size));
|
||||
}
|
||||
|
||||
void UBO::setDynamicData(uint32_t size, const void* data)
|
||||
{
|
||||
std::memcpy(_maps[_renderer->getActiveImageIndex()], data, static_cast<size_t>(size));
|
||||
_buffers[_renderer->getActiveImageIndex()].flush();
|
||||
}
|
||||
|
||||
unsigned int UBO::getSize() noexcept
|
||||
{
|
||||
return _buffers[_renderer->getActiveImageIndex()].getSize();
|
||||
}
|
||||
|
||||
unsigned int UBO::getOffset() noexcept
|
||||
{
|
||||
return _buffers[_renderer->getActiveImageIndex()].getOffset();
|
||||
}
|
||||
|
||||
VkBuffer& UBO::operator()() noexcept
|
||||
{
|
||||
return _buffers[_renderer->getActiveImageIndex()].get();
|
||||
}
|
||||
|
||||
VkBuffer& UBO::get() noexcept
|
||||
{
|
||||
return _buffers[_renderer->getActiveImageIndex()].get();
|
||||
}
|
||||
|
||||
void UBO::destroy() noexcept
|
||||
{
|
||||
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
||||
_buffers[i].destroy();
|
||||
}
|
||||
}
|
51
MacroLibX/src/renderer/buffers/vk_ubo.h
Normal file
51
MacroLibX/src/renderer/buffers/vk_ubo.h
Normal file
@ -0,0 +1,51 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* vk_ubo.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/06 18:45:29 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/08 19:06:28 by kbz_8 ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_VK_UBO__
|
||||
#define __MLX_VK_UBO__
|
||||
|
||||
#include "vk_buffer.h"
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <mlx_profile.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
class UBO
|
||||
{
|
||||
public:
|
||||
void create(class Renderer* renderer, uint32_t size, const char* name);
|
||||
|
||||
void setData(uint32_t size, const void* data);
|
||||
void setDynamicData(uint32_t size, const void* data);
|
||||
|
||||
void destroy() noexcept;
|
||||
|
||||
unsigned int getSize() noexcept;
|
||||
unsigned int getOffset() noexcept;
|
||||
VkDeviceMemory getDeviceMemory() noexcept;
|
||||
VkBuffer& operator()() noexcept;
|
||||
VkBuffer& get() noexcept;
|
||||
|
||||
inline unsigned int getSize(int i) noexcept { return _buffers[i].getSize(); }
|
||||
inline unsigned int getOffset(int i) noexcept { return _buffers[i].getOffset(); }
|
||||
inline VkBuffer& operator()(int i) noexcept { return _buffers[i].get(); }
|
||||
inline VkBuffer& get(int i) noexcept { return _buffers[i].get(); }
|
||||
|
||||
private:
|
||||
std::array<Buffer, MAX_FRAMES_IN_FLIGHT> _buffers;
|
||||
std::array<void*, MAX_FRAMES_IN_FLIGHT> _maps;
|
||||
class Renderer* _renderer = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // __MLX_VK_UBO__
|
55
MacroLibX/src/renderer/buffers/vk_vbo.cpp
Normal file
55
MacroLibX/src/renderer/buffers/vk_vbo.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* vk_vbo.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/06 18:28:08 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/12 22:17:14 by kbz_8 ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "vk_vbo.h"
|
||||
#include <cstring>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
void VBO::setData(uint32_t size, const void* data)
|
||||
{
|
||||
if(size > getSize())
|
||||
{
|
||||
core::error::report(e_kind::error, "Vulkan : trying to store to much data in a vertex buffer (%d bytes in %d bytes)", size, getSize());
|
||||
return;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
void D_VBO::setData(uint32_t size, const void* data)
|
||||
{
|
||||
if(size > getSize())
|
||||
{
|
||||
core::error::report(e_kind::error, "Vulkan : trying to store to much data in a vertex buffer (%d bytes in %d bytes)", size, getSize());
|
||||
return;
|
||||
}
|
||||
|
||||
if(data == nullptr)
|
||||
core::error::report(e_kind::warning, "Vulkan : mapping null data in a vertex buffer");
|
||||
|
||||
Buffer tmp_buf;
|
||||
#ifdef DEBUG
|
||||
tmp_buf.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, "tmp_buffer", data);
|
||||
#else
|
||||
tmp_buf.create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, nullptr, data);
|
||||
#endif
|
||||
copyFromBuffer(tmp_buf);
|
||||
tmp_buf.destroy();
|
||||
}
|
||||
}
|
46
MacroLibX/src/renderer/buffers/vk_vbo.h
Normal file
46
MacroLibX/src/renderer/buffers/vk_vbo.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* vk_vbo.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/06 18:27:38 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/12 22:46:21 by kbz_8 ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_VK_VBO__
|
||||
#define __MLX_VK_VBO__
|
||||
|
||||
#include "vk_buffer.h"
|
||||
#include <renderer/renderer.h>
|
||||
#include <mlx_profile.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
class VBO : public Buffer
|
||||
{
|
||||
public:
|
||||
inline void create(uint32_t size, const void* data, const char* name) { Buffer::create(Buffer::kind::dynamic, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, name, data); }
|
||||
void setData(uint32_t size, const void* data);
|
||||
inline void bind(Renderer& renderer) noexcept { vkCmdBindVertexBuffers(renderer.getActiveCmdBuffer().get(), 0, 1, &_buffer, &_offset); }
|
||||
};
|
||||
|
||||
class D_VBO : public Buffer
|
||||
{
|
||||
public:
|
||||
inline void create(uint32_t size, const void* data, const char* name) { Buffer::create(Buffer::kind::dynamic_device_local, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, name, data); }
|
||||
void setData(uint32_t size, const void* data);
|
||||
inline void bind(Renderer& renderer) noexcept { vkCmdBindVertexBuffers(renderer.getActiveCmdBuffer().get(), 0, 1, &_buffer, &_offset); }
|
||||
};
|
||||
|
||||
class C_VBO : public Buffer
|
||||
{
|
||||
public:
|
||||
inline void create(uint32_t size, const void* data, const char* name) { Buffer::create(Buffer::kind::constant, size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, name, data); }
|
||||
inline void bind(Renderer& renderer) noexcept { vkCmdBindVertexBuffers(renderer.getActiveCmdBuffer().get(), 0, 1, &_buffer, &_offset); }
|
||||
};
|
||||
}
|
||||
|
||||
#endif // __MLX_VK_VBO__
|
40
MacroLibX/src/renderer/command/cmd_manager.cpp
Normal file
40
MacroLibX/src/renderer/command/cmd_manager.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* cmd_manager.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/04/02 17:50:52 by maldavid #+# #+# */
|
||||
/* Updated: 2023/04/02 17:51:46 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <renderer/command/cmd_manager.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
void CmdManager::init() noexcept
|
||||
{
|
||||
_cmd_pool.init();
|
||||
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
||||
_cmd_buffers[i].init(this);
|
||||
}
|
||||
|
||||
void CmdManager::beginRecord(int active_image_index)
|
||||
{
|
||||
_cmd_buffers[active_image_index].beginRecord();
|
||||
}
|
||||
|
||||
void CmdManager::endRecord(int active_image_index)
|
||||
{
|
||||
_cmd_buffers[active_image_index].endRecord();
|
||||
}
|
||||
|
||||
void CmdManager::destroy() noexcept
|
||||
{
|
||||
for(int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
||||
_cmd_buffers[i].destroy();
|
||||
_cmd_pool.destroy();
|
||||
}
|
||||
}
|
47
MacroLibX/src/renderer/command/cmd_manager.h
Normal file
47
MacroLibX/src/renderer/command/cmd_manager.h
Normal file
@ -0,0 +1,47 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* cmd_manager.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/04/02 17:48:52 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/03 15:27:35 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_COMMAND_MANAGER__
|
||||
#define __MLX_COMMAND_MANAGER__
|
||||
|
||||
#include <array>
|
||||
|
||||
#include <mlx_profile.h>
|
||||
#include <volk.h>
|
||||
#include <renderer/core/render_core.h>
|
||||
#include <renderer/command/vk_cmd_pool.h>
|
||||
#include <renderer/command/vk_cmd_buffer.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
class CmdManager
|
||||
{
|
||||
public:
|
||||
CmdManager() = default;
|
||||
|
||||
void init() noexcept;
|
||||
void beginRecord(int active_image_index);
|
||||
void endRecord(int active_image_index);
|
||||
void destroy() noexcept;
|
||||
|
||||
inline CmdPool& getCmdPool() noexcept { return _cmd_pool; }
|
||||
inline CmdBuffer& getCmdBuffer(int i) noexcept { return _cmd_buffers[i]; }
|
||||
|
||||
~CmdManager() = default;
|
||||
|
||||
private:
|
||||
std::array<CmdBuffer, MAX_FRAMES_IN_FLIGHT> _cmd_buffers;
|
||||
CmdPool _cmd_pool;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
53
MacroLibX/src/renderer/command/single_time_cmd_manager.cpp
Normal file
53
MacroLibX/src/renderer/command/single_time_cmd_manager.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* single_time_cmd_manager.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/12/15 19:57:49 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/16 18:46:26 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <algorithm>
|
||||
#include <renderer/command/single_time_cmd_manager.h>
|
||||
#include <renderer/core/render_core.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
SingleTimeCmdManager::SingleTimeCmdManager() : _buffers(MIN_POOL_SIZE) {}
|
||||
|
||||
void SingleTimeCmdManager::init() noexcept
|
||||
{
|
||||
_pool.init();
|
||||
for(int i = 0; i < MIN_POOL_SIZE; i++)
|
||||
{
|
||||
_buffers.emplace_back();
|
||||
_buffers.back().init(&_pool);
|
||||
}
|
||||
}
|
||||
|
||||
CmdBuffer& SingleTimeCmdManager::getCmdBuffer() noexcept
|
||||
{
|
||||
for(CmdBuffer& buf : _buffers)
|
||||
{
|
||||
if(buf.isReadyToBeUsed())
|
||||
{
|
||||
buf.reset();
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
_buffers.emplace_back().init(&_pool);
|
||||
return _buffers.back();
|
||||
}
|
||||
|
||||
void SingleTimeCmdManager::destroy() noexcept
|
||||
{
|
||||
std::for_each(_buffers.begin(), _buffers.end(), [](CmdBuffer& buf)
|
||||
{
|
||||
buf.destroy();
|
||||
});
|
||||
_pool.destroy();
|
||||
}
|
||||
}
|
46
MacroLibX/src/renderer/command/single_time_cmd_manager.h
Normal file
46
MacroLibX/src/renderer/command/single_time_cmd_manager.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* single_time_cmd_manager.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/12/15 18:25:57 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/16 18:09:56 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_SINGLE_TIME_CMD_MANAGER__
|
||||
#define __MLX_SINGLE_TIME_CMD_MANAGER__
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <renderer/command/vk_cmd_pool.h>
|
||||
#include <renderer/command/vk_cmd_buffer.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
class SingleTimeCmdManager
|
||||
{
|
||||
public:
|
||||
SingleTimeCmdManager();
|
||||
|
||||
void init() noexcept;
|
||||
void destroy() noexcept;
|
||||
|
||||
inline CmdPool& getCmdPool() noexcept { return _pool; }
|
||||
CmdBuffer& getCmdBuffer() noexcept;
|
||||
|
||||
~SingleTimeCmdManager() = default;
|
||||
|
||||
inline static constexpr const uint8_t MIN_POOL_SIZE = 8;
|
||||
|
||||
private:
|
||||
|
||||
private:
|
||||
std::vector<CmdBuffer> _buffers;
|
||||
CmdPool _pool;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
137
MacroLibX/src/renderer/command/vk_cmd_buffer.cpp
Normal file
137
MacroLibX/src/renderer/command/vk_cmd_buffer.cpp
Normal file
@ -0,0 +1,137 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* vk_cmd_buffer.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/06 18:26:06 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/03 13:12:58 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "vk_cmd_buffer.h"
|
||||
#include <renderer/core/render_core.h>
|
||||
#include <renderer/command/cmd_manager.h>
|
||||
#include <renderer/core/vk_semaphore.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
void CmdBuffer::init(CmdManager* manager)
|
||||
{
|
||||
init(&manager->getCmdPool());
|
||||
}
|
||||
|
||||
void CmdBuffer::init(CmdPool* pool)
|
||||
{
|
||||
_pool = pool;
|
||||
|
||||
VkCommandBufferAllocateInfo allocInfo{};
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
allocInfo.commandPool = pool->get();
|
||||
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
allocInfo.commandBufferCount = 1;
|
||||
|
||||
VkResult res = vkAllocateCommandBuffers(Render_Core::get().getDevice().get(), &allocInfo, &_cmd_buffer);
|
||||
if(res != VK_SUCCESS)
|
||||
core::error::report(e_kind::fatal_error, "Vulkan : failed to allocate command buffer, %s", RCore::verbaliseResultVk(res));
|
||||
#ifdef DEBUG
|
||||
core::error::report(e_kind::message, "Vulkan : created new command buffer");
|
||||
#endif
|
||||
|
||||
_fence.init();
|
||||
_state = state::idle;
|
||||
}
|
||||
|
||||
void CmdBuffer::beginRecord(VkCommandBufferUsageFlags usage)
|
||||
{
|
||||
if(!isInit())
|
||||
core::error::report(e_kind::fatal_error, "Vulkan : begenning record on un uninit command buffer");
|
||||
if(_state == state::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");
|
||||
|
||||
_state = state::recording;
|
||||
}
|
||||
|
||||
void CmdBuffer::endRecord()
|
||||
{
|
||||
if(!isInit())
|
||||
core::error::report(e_kind::fatal_error, "Vulkan : ending record on un uninit command buffer");
|
||||
if(_state != state::recording)
|
||||
return;
|
||||
if(vkEndCommandBuffer(_cmd_buffer) != VK_SUCCESS)
|
||||
core::error::report(e_kind::fatal_error, "Vulkan : failed to end recording command buffer");
|
||||
|
||||
_state = state::idle;
|
||||
}
|
||||
|
||||
void CmdBuffer::submitIdle() noexcept
|
||||
{
|
||||
auto device = Render_Core::get().getDevice().get();
|
||||
|
||||
VkSubmitInfo submitInfo = {};
|
||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &_cmd_buffer;
|
||||
|
||||
VkFenceCreateInfo fenceCreateInfo = {};
|
||||
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
|
||||
VkFence fence;
|
||||
vkCreateFence(device, &fenceCreateInfo, nullptr, &fence);
|
||||
vkResetFences(device, 1, &fence);
|
||||
VkResult res = vkQueueSubmit(Render_Core::get().getQueue().getGraphic(), 1, &submitInfo, fence);
|
||||
if(res != VK_SUCCESS)
|
||||
core::error::report(e_kind::fatal_error, "Vulkan error : failed to submit a single time command buffer, %s", RCore::verbaliseResultVk(res));
|
||||
_state = state::submitted;
|
||||
vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX);
|
||||
vkDestroyFence(device, fence, nullptr);
|
||||
_state = state::ready;
|
||||
}
|
||||
|
||||
void CmdBuffer::submit(Semaphore* semaphores) noexcept
|
||||
{
|
||||
std::array<VkSemaphore, 1> signalSemaphores;
|
||||
std::array<VkSemaphore, 1> waitSemaphores;
|
||||
|
||||
if(semaphores != nullptr)
|
||||
{
|
||||
signalSemaphores[0] = semaphores->getRenderImageSemaphore();
|
||||
waitSemaphores[0] = semaphores->getImageSemaphore();
|
||||
}
|
||||
else
|
||||
{
|
||||
signalSemaphores[0] = nullptr;
|
||||
waitSemaphores[0] = nullptr;
|
||||
}
|
||||
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
|
||||
|
||||
VkSubmitInfo submitInfo{};
|
||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
submitInfo.waitSemaphoreCount = (semaphores == nullptr ? 0 : waitSemaphores.size());
|
||||
submitInfo.pWaitSemaphores = waitSemaphores.data();
|
||||
submitInfo.pWaitDstStageMask = waitStages;
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &_cmd_buffer;
|
||||
submitInfo.signalSemaphoreCount = (semaphores == nullptr ? 0 : signalSemaphores.size());
|
||||
submitInfo.pSignalSemaphores = signalSemaphores.data();
|
||||
|
||||
VkResult res = vkQueueSubmit(Render_Core::get().getQueue().getGraphic(), 1, &submitInfo, _fence.get());
|
||||
if(res != VK_SUCCESS)
|
||||
core::error::report(e_kind::fatal_error, "Vulkan error : failed to submit draw command buffer, %s", RCore::verbaliseResultVk(res));
|
||||
_state = state::submitted;
|
||||
}
|
||||
|
||||
void CmdBuffer::destroy() noexcept
|
||||
{
|
||||
_fence.destroy();
|
||||
_cmd_buffer = VK_NULL_HANDLE;
|
||||
_state = state::uninit;
|
||||
}
|
||||
}
|
64
MacroLibX/src/renderer/command/vk_cmd_buffer.h
Normal file
64
MacroLibX/src/renderer/command/vk_cmd_buffer.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* vk_cmd_buffer.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/06 18:25:42 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/03 15:27:20 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_VK_CMD_BUFFER__
|
||||
#define __MLX_VK_CMD_BUFFER__
|
||||
|
||||
#include <mlx_profile.h>
|
||||
#include <volk.h>
|
||||
#include <renderer/core/vk_fence.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
class CmdBuffer
|
||||
{
|
||||
public:
|
||||
enum class state
|
||||
{
|
||||
uninit = 0, // buffer not initialized or destroyed
|
||||
ready, // buffer ready to be used after having been submitted
|
||||
idle, // buffer has recorded informations but has not been submitted
|
||||
recording, // buffer is currently recording
|
||||
submitted, // buffer has been submitted
|
||||
};
|
||||
|
||||
public:
|
||||
void init(class CmdManager* manager);
|
||||
void init(class CmdPool* pool);
|
||||
void destroy() noexcept;
|
||||
|
||||
void beginRecord(VkCommandBufferUsageFlags usage = 0);
|
||||
void submit(class Semaphore* semaphores) noexcept;
|
||||
void submitIdle() noexcept;
|
||||
inline void waitForExecution() noexcept { _fence.waitAndReset(); _state = state::ready; }
|
||||
inline void reset() noexcept { vkResetCommandBuffer(_cmd_buffer, 0); }
|
||||
void endRecord();
|
||||
|
||||
inline bool isInit() const noexcept { return _state != state::uninit; }
|
||||
inline bool isReadyToBeUsed() const noexcept { return _state == state::ready; }
|
||||
inline bool isRecording() const noexcept { return _state == state::recording; }
|
||||
inline bool hasBeenSubmitted() const noexcept { return _state == state::submitted; }
|
||||
inline state getCurrentState() const noexcept { return _state; }
|
||||
|
||||
inline VkCommandBuffer& operator()() noexcept { return _cmd_buffer; }
|
||||
inline VkCommandBuffer& get() noexcept { return _cmd_buffer; }
|
||||
inline Fence& getFence() noexcept { return _fence; }
|
||||
|
||||
private:
|
||||
Fence _fence;
|
||||
VkCommandBuffer _cmd_buffer = VK_NULL_HANDLE;
|
||||
class CmdPool* _pool = nullptr;
|
||||
state _state = state::uninit;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // __MLX_VK_CMD_BUFFER__
|
35
MacroLibX/src/renderer/command/vk_cmd_pool.cpp
Normal file
35
MacroLibX/src/renderer/command/vk_cmd_pool.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* vk_cmd_pool.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/06 18:24:33 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/03 13:13:25 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().getFamilies().graphicsFamily.value();
|
||||
|
||||
VkResult res = vkCreateCommandPool(Render_Core::get().getDevice().get(), &poolInfo, nullptr, &_cmd_pool);
|
||||
if(res != VK_SUCCESS)
|
||||
core::error::report(e_kind::fatal_error, "Vulkan : failed to create command pool, %s", RCore::verbaliseResultVk(res));
|
||||
}
|
||||
|
||||
void CmdPool::destroy() noexcept
|
||||
{
|
||||
vkDestroyCommandPool(Render_Core::get().getDevice().get(), _cmd_pool, nullptr);
|
||||
_cmd_pool = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
35
MacroLibX/src/renderer/command/vk_cmd_pool.h
Normal file
35
MacroLibX/src/renderer/command/vk_cmd_pool.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* vk_cmd_pool.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/06 18:24:12 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/03 15:27:26 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_VK_CMD_POOL__
|
||||
#define __MLX_VK_CMD_POOL__
|
||||
|
||||
#include <mlx_profile.h>
|
||||
#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__
|
183
MacroLibX/src/renderer/core/memory.cpp
Normal file
183
MacroLibX/src/renderer/core/memory.cpp
Normal file
@ -0,0 +1,183 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* memory.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: kbz_8 <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/10/20 22:02:37 by kbz_8 #+# #+# */
|
||||
/* Updated: 2024/01/03 13:09:40 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <mlx_profile.h>
|
||||
#include <core/errors.h>
|
||||
#include <cstdio>
|
||||
|
||||
#define VMA_STATIC_VULKAN_FUNCTIONS 0
|
||||
#define VMA_DYNAMIC_VULKAN_FUNCTIONS 0
|
||||
#define VMA_VULKAN_VERSION 1002000
|
||||
#define VMA_ASSERT(expr) ((void)0)
|
||||
#define VMA_IMPLEMENTATION
|
||||
|
||||
#ifdef MLX_COMPILER_CLANG
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Weverything"
|
||||
#include <renderer/core/memory.h>
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(MLX_COMPILER_GCC)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
|
||||
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#pragma GCC diagnostic ignored "-Wparentheses"
|
||||
#include <renderer/core/memory.h>
|
||||
#pragma GCC diagnostic pop
|
||||
#else
|
||||
#include <renderer/core/memory.h>
|
||||
#endif
|
||||
|
||||
#include <renderer/core/render_core.h>
|
||||
#include <fstream>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
void GPUallocator::init() noexcept
|
||||
{
|
||||
VmaVulkanFunctions vma_vulkan_func{};
|
||||
vma_vulkan_func.vkAllocateMemory = vkAllocateMemory;
|
||||
vma_vulkan_func.vkBindBufferMemory = vkBindBufferMemory;
|
||||
vma_vulkan_func.vkBindImageMemory = vkBindImageMemory;
|
||||
vma_vulkan_func.vkCreateBuffer = vkCreateBuffer;
|
||||
vma_vulkan_func.vkCreateImage = vkCreateImage;
|
||||
vma_vulkan_func.vkDestroyBuffer = vkDestroyBuffer;
|
||||
vma_vulkan_func.vkDestroyImage = vkDestroyImage;
|
||||
vma_vulkan_func.vkFlushMappedMemoryRanges = vkFlushMappedMemoryRanges;
|
||||
vma_vulkan_func.vkFreeMemory = vkFreeMemory;
|
||||
vma_vulkan_func.vkGetBufferMemoryRequirements = vkGetBufferMemoryRequirements;
|
||||
vma_vulkan_func.vkGetImageMemoryRequirements = vkGetImageMemoryRequirements;
|
||||
vma_vulkan_func.vkGetPhysicalDeviceMemoryProperties = vkGetPhysicalDeviceMemoryProperties;
|
||||
vma_vulkan_func.vkGetPhysicalDeviceProperties = vkGetPhysicalDeviceProperties;
|
||||
vma_vulkan_func.vkInvalidateMappedMemoryRanges = vkInvalidateMappedMemoryRanges;
|
||||
vma_vulkan_func.vkMapMemory = vkMapMemory;
|
||||
vma_vulkan_func.vkUnmapMemory = vkUnmapMemory;
|
||||
vma_vulkan_func.vkCmdCopyBuffer = vkCmdCopyBuffer;
|
||||
vma_vulkan_func.vkGetBufferMemoryRequirements2KHR = vkGetBufferMemoryRequirements2;
|
||||
vma_vulkan_func.vkGetImageMemoryRequirements2KHR = vkGetImageMemoryRequirements2;
|
||||
vma_vulkan_func.vkBindBufferMemory2KHR = vkBindBufferMemory2;
|
||||
vma_vulkan_func.vkBindImageMemory2KHR = vkBindImageMemory2;
|
||||
vma_vulkan_func.vkGetPhysicalDeviceMemoryProperties2KHR = vkGetPhysicalDeviceMemoryProperties2;
|
||||
|
||||
VmaAllocatorCreateInfo allocatorCreateInfo{};
|
||||
allocatorCreateInfo.vulkanApiVersion = VK_API_VERSION_1_2;
|
||||
allocatorCreateInfo.physicalDevice = Render_Core::get().getDevice().getPhysicalDevice();
|
||||
allocatorCreateInfo.device = Render_Core::get().getDevice().get();
|
||||
allocatorCreateInfo.instance = Render_Core::get().getInstance().get();
|
||||
allocatorCreateInfo.pVulkanFunctions = &vma_vulkan_func;
|
||||
|
||||
VkResult res = vmaCreateAllocator(&allocatorCreateInfo, &_allocator);
|
||||
if(res != VK_SUCCESS)
|
||||
core::error::report(e_kind::fatal_error, "Graphics allocator : failed to create graphics memory allocator, %s", RCore::verbaliseResultVk(res));
|
||||
#ifdef DEBUG
|
||||
core::error::report(e_kind::message, "Graphics allocator : created new allocator");
|
||||
#endif
|
||||
}
|
||||
|
||||
VmaAllocation GPUallocator::createBuffer(const VkBufferCreateInfo* binfo, const VmaAllocationCreateInfo* vinfo, VkBuffer& buffer, const char* name) noexcept
|
||||
{
|
||||
VmaAllocation allocation;
|
||||
VkResult res = vmaCreateBuffer(_allocator, binfo, vinfo, &buffer, &allocation, nullptr);
|
||||
if(res != VK_SUCCESS)
|
||||
core::error::report(e_kind::fatal_error, "Graphics allocator : failed to allocate a buffer, %s", RCore::verbaliseResultVk(res));
|
||||
if(name != nullptr)
|
||||
vmaSetAllocationName(_allocator, allocation, name);
|
||||
#ifdef DEBUG
|
||||
core::error::report(e_kind::message, "Graphics Allocator : created new buffer");
|
||||
#endif
|
||||
_active_buffers_allocations++;
|
||||
return allocation;
|
||||
}
|
||||
|
||||
void GPUallocator::destroyBuffer(VmaAllocation allocation, VkBuffer buffer) noexcept
|
||||
{
|
||||
vkDeviceWaitIdle(Render_Core::get().getDevice().get());
|
||||
vmaDestroyBuffer(_allocator, buffer, allocation);
|
||||
#ifdef DEBUG
|
||||
core::error::report(e_kind::message, "Graphics Allocator : destroyed buffer");
|
||||
#endif
|
||||
_active_buffers_allocations--;
|
||||
}
|
||||
|
||||
VmaAllocation GPUallocator::createImage(const VkImageCreateInfo* iminfo, const VmaAllocationCreateInfo* vinfo, VkImage& image, const char* name) noexcept
|
||||
{
|
||||
VmaAllocation allocation;
|
||||
VkResult res = vmaCreateImage(_allocator, iminfo, vinfo, &image, &allocation, nullptr);
|
||||
if(res != VK_SUCCESS)
|
||||
core::error::report(e_kind::fatal_error, "Graphics allocator : failed to allocate an image, %s", RCore::verbaliseResultVk(res));
|
||||
if(name != nullptr)
|
||||
vmaSetAllocationName(_allocator, allocation, name);
|
||||
#ifdef DEBUG
|
||||
core::error::report(e_kind::message, "Graphics Allocator : created new image");
|
||||
#endif
|
||||
_active_images_allocations++;
|
||||
return allocation;
|
||||
}
|
||||
|
||||
void GPUallocator::destroyImage(VmaAllocation allocation, VkImage image) noexcept
|
||||
{
|
||||
vkDeviceWaitIdle(Render_Core::get().getDevice().get());
|
||||
vmaDestroyImage(_allocator, image, allocation);
|
||||
#ifdef DEBUG
|
||||
core::error::report(e_kind::message, "Graphics Allocator : destroyed image");
|
||||
#endif
|
||||
_active_images_allocations--;
|
||||
}
|
||||
|
||||
void GPUallocator::mapMemory(VmaAllocation allocation, void** data) noexcept
|
||||
{
|
||||
VkResult res = vmaMapMemory(_allocator, allocation, data);
|
||||
if(res != VK_SUCCESS)
|
||||
core::error::report(e_kind::fatal_error, "Graphics allocator : unable to map GPU memory to CPU memory, %s", RCore::verbaliseResultVk(res));
|
||||
}
|
||||
|
||||
void GPUallocator::unmapMemory(VmaAllocation allocation) noexcept
|
||||
{
|
||||
vmaUnmapMemory(_allocator, allocation);
|
||||
}
|
||||
|
||||
void GPUallocator::dumpMemoryToJson()
|
||||
{
|
||||
static uint32_t id = 0;
|
||||
std::string name("memory_dump");
|
||||
name.append(std::to_string(id) + ".json");
|
||||
std::ofstream file(name);
|
||||
if(!file.is_open())
|
||||
{
|
||||
core::error::report(e_kind::error, "Graphics allocator : unable to dump memory to a json file");
|
||||
return;
|
||||
}
|
||||
char* str = nullptr;
|
||||
vmaBuildStatsString(_allocator, &str, true);
|
||||
file << str;
|
||||
vmaFreeStatsString(_allocator, str);
|
||||
file.close();
|
||||
id++;
|
||||
}
|
||||
|
||||
void GPUallocator::flush(VmaAllocation allocation, VkDeviceSize size, VkDeviceSize offset) noexcept
|
||||
{
|
||||
vmaFlushAllocation(_allocator, allocation, offset, size);
|
||||
}
|
||||
|
||||
void GPUallocator::destroy() noexcept
|
||||
{
|
||||
if(_active_images_allocations != 0)
|
||||
core::error::report(e_kind::error, "Graphics allocator : some user-dependant allocations were not freed before destroying the display (%d active allocations)", _active_images_allocations);
|
||||
else if(_active_buffers_allocations != 0)
|
||||
core::error::report(e_kind::error, "Graphics allocator : some MLX-dependant allocations were not freed before destroying the display (%d active allocations), please report, this should not happen", _active_buffers_allocations);
|
||||
vmaDestroyAllocator(_allocator);
|
||||
_active_buffers_allocations = 0;
|
||||
_active_images_allocations = 0;
|
||||
}
|
||||
}
|
52
MacroLibX/src/renderer/core/memory.h
Normal file
52
MacroLibX/src/renderer/core/memory.h
Normal file
@ -0,0 +1,52 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* memory.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/10/20 02:13:03 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/03 15:25:56 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_VK_MEMORY__
|
||||
#define __MLX_VK_MEMORY__
|
||||
|
||||
#include <mlx_profile.h>
|
||||
#include <volk.h>
|
||||
#include <vma.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
class GPUallocator
|
||||
{
|
||||
public:
|
||||
GPUallocator() = default;
|
||||
|
||||
void init() noexcept;
|
||||
void destroy() noexcept;
|
||||
|
||||
VmaAllocation createBuffer(const VkBufferCreateInfo* binfo, const VmaAllocationCreateInfo* vinfo, VkBuffer& buffer, const char* name = nullptr) noexcept;
|
||||
void destroyBuffer(VmaAllocation allocation, VkBuffer buffer) noexcept;
|
||||
|
||||
VmaAllocation createImage(const VkImageCreateInfo* iminfo, const VmaAllocationCreateInfo* vinfo, VkImage& image, const char* name = nullptr) noexcept;
|
||||
void destroyImage(VmaAllocation allocation, VkImage image) noexcept;
|
||||
|
||||
void mapMemory(VmaAllocation allocation, void** data) noexcept;
|
||||
void unmapMemory(VmaAllocation allocation) noexcept;
|
||||
|
||||
void dumpMemoryToJson();
|
||||
|
||||
void flush(VmaAllocation allocation, VkDeviceSize size, VkDeviceSize offset) noexcept;
|
||||
|
||||
~GPUallocator() = default;
|
||||
|
||||
private:
|
||||
VmaAllocator _allocator;
|
||||
uint32_t _active_buffers_allocations = 0;
|
||||
uint32_t _active_images_allocations = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
111
MacroLibX/src/renderer/core/render_core.cpp
Normal file
111
MacroLibX/src/renderer/core/render_core.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* render_core.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/12/17 23:33:34 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/03 15:22:38 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#define VOLK_IMPLEMENTATION
|
||||
|
||||
#include <mlx_profile.h>
|
||||
#include <renderer/core/render_core.h>
|
||||
#include <mutex>
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef MLX_COMPILER_MSVC
|
||||
#pragma NOTE("MLX is being compiled in debug mode, this activates Vulkan's validation layers and debug messages which may impact rendering performances")
|
||||
#else
|
||||
#warning "MLX is being compiled in debug mode, this activates Vulkan's validation layers and debug messages which may impact rendering performances"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
namespace RCore
|
||||
{
|
||||
std::optional<uint32_t> findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties, bool error)
|
||||
{
|
||||
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;
|
||||
}
|
||||
if(error)
|
||||
core::error::report(e_kind::fatal_error, "Vulkan : failed to find suitable memory type");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Render_Core::init()
|
||||
{
|
||||
if(volkInitialize() != VK_SUCCESS)
|
||||
core::error::report(e_kind::fatal_error, "Vulkan loader : cannot load %s, are you sure Vulkan is installed on your system ?", VULKAN_LIB_NAME);
|
||||
|
||||
_instance.init();
|
||||
volkLoadInstance(_instance.get());
|
||||
_layers.init();
|
||||
_device.init();
|
||||
volkLoadDevice(_device.get());
|
||||
_queues.init();
|
||||
_allocator.init();
|
||||
_cmd_manager.init();
|
||||
_is_init = true;
|
||||
}
|
||||
|
||||
void Render_Core::destroy()
|
||||
{
|
||||
if(!_is_init)
|
||||
return;
|
||||
|
||||
vkDeviceWaitIdle(_device());
|
||||
|
||||
_cmd_manager.destroy();
|
||||
_allocator.destroy();
|
||||
_device.destroy();
|
||||
_layers.destroy();
|
||||
_instance.destroy();
|
||||
|
||||
_is_init = false;
|
||||
}
|
||||
}
|
76
MacroLibX/src/renderer/core/render_core.h
Normal file
76
MacroLibX/src/renderer/core/render_core.h
Normal file
@ -0,0 +1,76 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* render_core.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/08 19:16:32 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/03 15:26:08 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_RENDER_CORE__
|
||||
#define __MLX_RENDER_CORE__
|
||||
|
||||
#include <mlx_profile.h>
|
||||
#include <volk.h>
|
||||
#include <optional>
|
||||
|
||||
#include <renderer/command/single_time_cmd_manager.h>
|
||||
#include "vk_queues.h"
|
||||
#include "vk_device.h"
|
||||
#include "vk_instance.h"
|
||||
#include "vk_validation_layers.h"
|
||||
#include "memory.h"
|
||||
|
||||
#include <utils/singleton.h>
|
||||
#include <core/errors.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
namespace RCore
|
||||
{
|
||||
std::optional<uint32_t> findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties, bool error = true);
|
||||
const char* verbaliseResultVk(VkResult result);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
constexpr const bool enableValidationLayers = true;
|
||||
#else
|
||||
constexpr const bool enableValidationLayers = false;
|
||||
#endif
|
||||
|
||||
const std::vector<const char*> validationLayers = { "VK_LAYER_KHRONOS_validation" };
|
||||
|
||||
constexpr const int MAX_FRAMES_IN_FLIGHT = 3;
|
||||
|
||||
class Render_Core : public Singleton<Render_Core>
|
||||
{
|
||||
public:
|
||||
Render_Core() = default;
|
||||
|
||||
void init();
|
||||
void destroy();
|
||||
|
||||
inline Instance& getInstance() noexcept { return _instance; }
|
||||
inline Device& getDevice() noexcept { return _device; }
|
||||
inline Queues& getQueue() noexcept { return _queues; }
|
||||
inline GPUallocator& getAllocator() noexcept { return _allocator; }
|
||||
inline ValidationLayers& getLayers() noexcept { return _layers; }
|
||||
inline CmdBuffer& getSingleTimeCmdBuffer() noexcept { return _cmd_manager.getCmdBuffer(); }
|
||||
|
||||
~Render_Core() = default;
|
||||
|
||||
private:
|
||||
ValidationLayers _layers;
|
||||
SingleTimeCmdManager _cmd_manager;
|
||||
Queues _queues;
|
||||
Device _device;
|
||||
Instance _instance;
|
||||
GPUallocator _allocator;
|
||||
bool _is_init = false;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // __MLX_RENDER_CORE__
|
163
MacroLibX/src/renderer/core/vk_device.cpp
Normal file
163
MacroLibX/src/renderer/core/vk_device.cpp
Normal file
@ -0,0 +1,163 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* vk_device.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/08 19:14:29 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/30 23:29:41 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "render_core.h"
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_vulkan.h>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
const std::vector<const char*> deviceExtensions = {VK_KHR_SWAPCHAIN_EXTENSION_NAME};
|
||||
|
||||
void Device::init()
|
||||
{
|
||||
pickPhysicalDevice();
|
||||
|
||||
Queues::QueueFamilyIndices indices = Render_Core::get().getQueue().getFamilies();
|
||||
|
||||
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;
|
||||
|
||||
VkResult res;
|
||||
if((res = vkCreateDevice(_physicalDevice, &createInfo, nullptr, &_device)) != VK_SUCCESS)
|
||||
core::error::report(e_kind::fatal_error, "Vulkan : failed to create logcal device, %s", RCore::verbaliseResultVk(res));
|
||||
#ifdef DEBUG
|
||||
core::error::report(e_kind::message, "Vulkan : created new logical device");
|
||||
#endif
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
SDL_Window* window = SDL_CreateWindow("", 0, 0, 1, 1, SDL_WINDOW_VULKAN | SDL_WINDOW_HIDDEN);
|
||||
if(!window)
|
||||
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a window to pick physical device");
|
||||
|
||||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||
if(SDL_Vulkan_CreateSurface(window, Render_Core::get().getInstance().get(), &surface) != SDL_TRUE)
|
||||
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a surface to pick physical device");
|
||||
|
||||
std::vector<std::pair<int, VkPhysicalDevice>> devices_score;
|
||||
|
||||
std::transform(devices.cbegin(), devices.cend(), std::back_inserter(devices_score), [&](VkPhysicalDevice device)
|
||||
{
|
||||
return std::make_pair(deviceScore(device, surface), device);
|
||||
});
|
||||
|
||||
vkDestroySurfaceKHR(Render_Core::get().getInstance().get(), surface, nullptr);
|
||||
SDL_DestroyWindow(window);
|
||||
|
||||
using device_pair = std::pair<int, VkPhysicalDevice>;
|
||||
std::sort(devices_score.begin(), devices_score.end(), [](const device_pair& a, const device_pair& b)
|
||||
{
|
||||
return a.first > b.first;
|
||||
});
|
||||
|
||||
if(devices_score.front().first > 0)
|
||||
_physicalDevice = devices_score.front().second;
|
||||
|
||||
if(_physicalDevice == VK_NULL_HANDLE)
|
||||
core::error::report(e_kind::fatal_error, "Vulkan : failed to find a suitable GPU");
|
||||
#ifdef DEBUG
|
||||
VkPhysicalDeviceProperties props;
|
||||
vkGetPhysicalDeviceProperties(_physicalDevice, &props);
|
||||
core::error::report(e_kind::message, "Vulkan : picked a physical device, %s", props.deviceName);
|
||||
#endif
|
||||
}
|
||||
|
||||
int Device::deviceScore(VkPhysicalDevice device, VkSurfaceKHR surface)
|
||||
{
|
||||
Queues::QueueFamilyIndices indices = Render_Core::get().getQueue().findQueueFamilies(device, surface);
|
||||
bool extensionsSupported = checkDeviceExtensionSupport(device);
|
||||
|
||||
uint32_t formatCount = 0;
|
||||
if(extensionsSupported)
|
||||
vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, nullptr);
|
||||
|
||||
VkPhysicalDeviceProperties props;
|
||||
vkGetPhysicalDeviceProperties(device, &props);
|
||||
if(!indices.isComplete() || !extensionsSupported || formatCount == 0)
|
||||
return -1;
|
||||
|
||||
int score = 0;
|
||||
#ifndef FORCE_INTEGRATED_GPU
|
||||
if(props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
|
||||
score += 1000;
|
||||
#else
|
||||
if(props.deviceType != VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU)
|
||||
return -1;
|
||||
#endif
|
||||
score += props.limits.maxImageDimension2D;
|
||||
score += props.limits.maxBoundDescriptorSets;
|
||||
return score;
|
||||
}
|
||||
|
||||
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);
|
||||
_device = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
44
MacroLibX/src/renderer/core/vk_device.h
Normal file
44
MacroLibX/src/renderer/core/vk_device.h
Normal file
@ -0,0 +1,44 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* vk_device.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/08 19:13:42 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/03 15:26:14 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_VK_DEVICE__
|
||||
#define __MLX_VK_DEVICE__
|
||||
|
||||
#include <mlx_profile.h>
|
||||
#include <volk.h>
|
||||
#include "vk_queues.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 checkDeviceExtensionSupport(VkPhysicalDevice device);
|
||||
int deviceScore(VkPhysicalDevice device, VkSurfaceKHR surface);
|
||||
|
||||
private:
|
||||
VkPhysicalDevice _physicalDevice = VK_NULL_HANDLE;
|
||||
VkDevice _device = VK_NULL_HANDLE;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // __MLX_VK_DEVICE__
|
53
MacroLibX/src/renderer/core/vk_fence.cpp
Normal file
53
MacroLibX/src/renderer/core/vk_fence.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* vk_fence.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/04/02 17:53:06 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/16 18:47:36 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include <renderer/core/vk_fence.h>
|
||||
#include <renderer/core/render_core.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
void Fence::init()
|
||||
{
|
||||
VkFenceCreateInfo fenceInfo{};
|
||||
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||
|
||||
VkResult res;
|
||||
if((res = vkCreateFence(Render_Core::get().getDevice().get(), &fenceInfo, nullptr, &_fence)) != VK_SUCCESS)
|
||||
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a synchronization object (fence), %s", RCore::verbaliseResultVk(res));
|
||||
#ifdef DEBUG
|
||||
core::error::report(e_kind::message, "Vulkan : created new fence");
|
||||
#endif
|
||||
}
|
||||
|
||||
void Fence::wait() noexcept
|
||||
{
|
||||
vkWaitForFences(Render_Core::get().getDevice().get(), 1, &_fence, VK_TRUE, UINT64_MAX);
|
||||
}
|
||||
|
||||
void Fence::reset() noexcept
|
||||
{
|
||||
vkResetFences(Render_Core::get().getDevice().get(), 1, &_fence);
|
||||
}
|
||||
|
||||
bool Fence::isReady() const noexcept
|
||||
{
|
||||
return vkGetFenceStatus(Render_Core::get().getDevice().get(), _fence) == VK_SUCCESS;
|
||||
}
|
||||
|
||||
void Fence::destroy() noexcept
|
||||
{
|
||||
if(_fence != VK_NULL_HANDLE)
|
||||
vkDestroyFence(Render_Core::get().getDevice().get(), _fence, nullptr);
|
||||
_fence = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
43
MacroLibX/src/renderer/core/vk_fence.h
Normal file
43
MacroLibX/src/renderer/core/vk_fence.h
Normal file
@ -0,0 +1,43 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* vk_fence.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2023/04/02 17:52:09 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/03 15:26:21 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_VK_FENCE__
|
||||
#define __MLX_VK_FENCE__
|
||||
|
||||
#include <mlx_profile.h>
|
||||
#include <volk.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
class Fence
|
||||
{
|
||||
public:
|
||||
Fence() = default;
|
||||
|
||||
void init();
|
||||
|
||||
inline VkFence& get() noexcept { return _fence; }
|
||||
void wait() noexcept;
|
||||
void reset() noexcept;
|
||||
bool isReady() const noexcept;
|
||||
inline void waitAndReset() noexcept { wait(); reset(); }
|
||||
|
||||
void destroy() noexcept;
|
||||
|
||||
~Fence() = default;
|
||||
|
||||
private:
|
||||
VkFence _fence = VK_NULL_HANDLE;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
88
MacroLibX/src/renderer/core/vk_instance.cpp
Normal file
88
MacroLibX/src/renderer/core/vk_instance.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* vk_instance.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/08 19:04:21 by maldavid #+# #+# */
|
||||
/* Updated: 2023/12/31 00:40:10 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "vk_instance.h"
|
||||
#include "render_core.h"
|
||||
#include <platform/window.h>
|
||||
#include <SDL2/SDL_vulkan.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
void Instance::init()
|
||||
{
|
||||
VkApplicationInfo appInfo{};
|
||||
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||
appInfo.pEngineName = "MacroLibX";
|
||||
appInfo.engineVersion = VK_MAKE_VERSION(1, 2, 1);
|
||||
appInfo.apiVersion = VK_API_VERSION_1_2;
|
||||
|
||||
auto extensions = getRequiredExtensions();
|
||||
|
||||
VkInstanceCreateInfo createInfo{};
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||
createInfo.pApplicationInfo = &appInfo;
|
||||
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
|
||||
createInfo.ppEnabledExtensionNames = extensions.data();
|
||||
createInfo.enabledLayerCount = 0; // will be replaced if validation layers are enabled
|
||||
createInfo.pNext = nullptr;
|
||||
|
||||
VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo;
|
||||
if constexpr(enableValidationLayers)
|
||||
{
|
||||
if(Render_Core::get().getLayers().checkValidationLayerSupport())
|
||||
{
|
||||
createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
|
||||
createInfo.ppEnabledLayerNames = validationLayers.data();
|
||||
Render_Core::get().getLayers().populateDebugMessengerCreateInfo(debugCreateInfo);
|
||||
createInfo.pNext = static_cast<VkDebugUtilsMessengerCreateInfoEXT*>(&debugCreateInfo);
|
||||
}
|
||||
}
|
||||
|
||||
VkResult res;
|
||||
if((res = vkCreateInstance(&createInfo, nullptr, &_instance)) != VK_SUCCESS)
|
||||
core::error::report(e_kind::fatal_error, "Vulkan : failed to create Vulkan instance, %s", RCore::verbaliseResultVk(res));
|
||||
volkLoadInstance(_instance);
|
||||
#ifdef DEBUG
|
||||
core::error::report(e_kind::message, "Vulkan : created new instance");
|
||||
#endif
|
||||
}
|
||||
|
||||
std::vector<const char*> Instance::getRequiredExtensions()
|
||||
{
|
||||
unsigned int count = 0;
|
||||
SDL_Window* window = SDL_CreateWindow("", 0, 0, 1, 1, SDL_WINDOW_VULKAN | SDL_WINDOW_HIDDEN);
|
||||
if(!window)
|
||||
core::error::report(e_kind::fatal_error, "Vulkan : cannot get instance extentions from window : %s", SDL_GetError());
|
||||
|
||||
if(!SDL_Vulkan_GetInstanceExtensions(window, &count, nullptr))
|
||||
core::error::report(e_kind::fatal_error, "Vulkan : cannot get instance extentions from window : %s", SDL_GetError());
|
||||
|
||||
std::vector<const char*> extensions = { VK_EXT_DEBUG_REPORT_EXTENSION_NAME };
|
||||
size_t additional_extension_count = extensions.size();
|
||||
extensions.resize(additional_extension_count + count);
|
||||
|
||||
if(!SDL_Vulkan_GetInstanceExtensions(window, &count, extensions.data() + additional_extension_count))
|
||||
core::error::report(e_kind::error, "Vulkan : cannot get instance extentions from window : %s", SDL_GetError());
|
||||
|
||||
if constexpr(enableValidationLayers)
|
||||
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
|
||||
SDL_DestroyWindow(window);
|
||||
return extensions;
|
||||
}
|
||||
|
||||
void Instance::destroy() noexcept
|
||||
{
|
||||
vkDestroyInstance(_instance, nullptr);
|
||||
_instance = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
37
MacroLibX/src/renderer/core/vk_instance.h
Normal file
37
MacroLibX/src/renderer/core/vk_instance.h
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: 2024/01/03 15:26:26 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_VK_INSTANCE__
|
||||
#define __MLX_VK_INSTANCE__
|
||||
|
||||
#include <mlx_profile.h>
|
||||
#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__
|
68
MacroLibX/src/renderer/core/vk_queues.cpp
Normal file
68
MacroLibX/src/renderer/core/vk_queues.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* vk_queues.cpp :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/08 19:02:42 by maldavid #+# #+# */
|
||||
/* Updated: 2022/12/18 22:52:04 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "render_core.h"
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_vulkan.h>
|
||||
|
||||
namespace mlx
|
||||
{
|
||||
Queues::QueueFamilyIndices Queues::findQueueFamilies(VkPhysicalDevice device, VkSurfaceKHR surface)
|
||||
{
|
||||
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, surface, &presentSupport);
|
||||
|
||||
if(presentSupport)
|
||||
_families->presentFamily = i;
|
||||
|
||||
if(_families->isComplete())
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
|
||||
return *_families;
|
||||
}
|
||||
|
||||
void Queues::init()
|
||||
{
|
||||
if(!_families.has_value())
|
||||
{
|
||||
SDL_Window* window = SDL_CreateWindow("", 0, 0, 1, 1, SDL_WINDOW_VULKAN | SDL_WINDOW_HIDDEN);
|
||||
if(!window)
|
||||
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a window to init queues");
|
||||
|
||||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||
if(SDL_Vulkan_CreateSurface(window, Render_Core::get().getInstance().get(), &surface) != SDL_TRUE)
|
||||
core::error::report(e_kind::fatal_error, "Vulkan : failed to create a surface to init queues");
|
||||
|
||||
findQueueFamilies(Render_Core::get().getDevice().getPhysicalDevice(), surface);
|
||||
|
||||
vkDestroySurfaceKHR(Render_Core::get().getInstance().get(), surface, nullptr);
|
||||
SDL_DestroyWindow(window);
|
||||
}
|
||||
vkGetDeviceQueue(Render_Core::get().getDevice().get(), _families->graphicsFamily.value(), 0, &_graphicsQueue);
|
||||
vkGetDeviceQueue(Render_Core::get().getDevice().get(), _families->presentFamily.value(), 0, &_presentQueue);
|
||||
}
|
||||
}
|
49
MacroLibX/src/renderer/core/vk_queues.h
Normal file
49
MacroLibX/src/renderer/core/vk_queues.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* vk_queues.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maldavid <kbz_8.dev@akel-engine.com> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2022/10/08 19:01:49 by maldavid #+# #+# */
|
||||
/* Updated: 2024/01/03 15:26:31 by maldavid ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef __MLX_VK_QUEUES__
|
||||
#define __MLX_VK_QUEUES__
|
||||
|
||||
#include <mlx_profile.h>
|
||||
#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, VkSurfaceKHR surface);
|
||||
|
||||
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__
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user