A leckéhez tartozó teljes kód megtalálható a hozzá tartozó [github branch-en](https://git.sch.bme.hu/kszk/devteam/vulkan-workshop/-/tree/lecture_01-final).
# Inicializálás
Mielőtt nekilátnál a kódolásnak, hozz létre egy kiinduló projektet. A példák kiinduló kódja megtalálható [ezen a linken](https://git.sch.bme.hu/kszk/devteam/vulkan-workshop/-/tree/starter).
...
...
@@ -8,7 +12,7 @@ A példák Vulkan mellett [glm](https://github.com/g-truc/glm), [GLFW](https://w
## Általános
A workshop folyamán a [Vulkan hivatalos C++ binding-ja](https://github.com/KhronosGroup/Vulkan-Hpp)it fogjuk használni, és a kód részletek is C++20-ban lettek megírva.
A leckék során a [Vulkan hivatalos C++ binding-ja](https://github.com/KhronosGroup/Vulkan-Hpp)it fogjuk használni, és a kód részletek is C++20-ban lettek megírva.
## Instance
...
...
@@ -18,7 +22,7 @@ Bármilyen Vulkan kód kiinduló eleme egy `vk::Instance` (C-ben `VkInstance`) o
A C++ binding-ban [RAII támogatás](https://github.com/KhronosGroup/Vulkan-Hpp/blob/main/vk_raii_ProgrammingGuide.md) is adott. De ez tapasztalat alapján nekünk inkább csak a fordítást fogja lassítani, minthogy a kódolásban könnyedséget okozna.
Mivel ez egy Vulkan handle, ezért használat után nekünk kell "felszabadítani". Habár nem best practice, de mi minden ilyen handle helyett egy C++ `unique_ptr`-hez hasonló struktúrával fogjuk használni ezeket, amit a Vulkan binding biztosít.
Mivel ez egy általunk létrehozott erőforrás, ezért használat után is nekünk kell "felszabadítani". Habár nem feltétlen *best practice*, de mi minden ilyen *handle*-t egy C++ `unique_ptr`-hez hasonló struktúrába csomagolva fogunk használni, amit a Vulkan binding biztosít.
??? example "Hozzuk létre a `Renderer` osztályt!"
...
...
@@ -41,7 +45,8 @@ Mivel ez egy Vulkan handle, ezért használat után nekünk kell "felszabadítan
```cpp title="Renderer.cpp"
#include "Renderer.hpp"
[[nodiscard]] static auto create_instance() -> vk::UniqueInstance {
[[nodiscard]]
static auto create_instance() -> vk::UniqueInstance {
return {};
}
...
...
@@ -50,12 +55,14 @@ Mivel ez egy Vulkan handle, ezért használat után nekünk kell "felszabadítan
Bizonyos játékmotorokhoz és appokhoz külön hardveres támogatás van, amit a Vulkan-nak ilyenkor lehet jelezni.
Az applikációnk által használni tervezett legnagyobb API verzió *1.0* lesz.
Ezeket az értékeket gyűjti össze a `vk::Application` struct, amelyet mi default-inicializálunk.
Ezeket az értékeket gyűjti össze a `vk::ApplicationInfo`.
??? example "Hozzuk létre a `vk::ApplicationInfo`-t!"
@@ -105,7 +115,7 @@ Ezeknél több mindent is beállíthatnánk még az Instance létrehozásához,
## Physical Device
Minden a gépen jelen levő Vulkan-képes processzort egy `vk::PhysicalDevice`-al reprezentál könyvtár. Ezeket a `vk::Instance::enumeratePhysicalDevices` függvénnyel le is kérhetjük.
Minden a gépen jelen levő Vulkan-képes processzort egy `vk::PhysicalDevice`-al reprezentál a könyvtár. Ezeket a `vk::Instance::enumeratePhysicalDevices` függvénnyel le is kérhetjük.
Érdemes egy diszkrét GPU-val dolgozni, ha az jelen van, rosszabb esetben integrálttal. Így válasszuk ki a számunkra legmegfelelőbb egységet.
...
...
@@ -121,14 +131,13 @@ Minden a gépen jelen levő Vulkan-képes processzort egy `vk::PhysicalDevice`-a
@@ -152,22 +161,23 @@ Minden a gépen jelen levő Vulkan-képes processzort egy `vk::PhysicalDevice`-a
Mielőtt elkezdünk a GPU-n dolgozni, azelőtt elengedhetetlen a használni tervezett extra funkciók megadása. Egyelőre ezzel mi még nem élünk.
A (Logical) Device szintaktikailag nagyon hasonlít az Instance-hez. Itt is lesz olyan, amit majd csak később állítunk be. A mostani alkalommal egyedül a `vk::Queue`-kra fogunk koncentrálunk.
A (Logical) Device szintaktikailag nagyon hasonlít az Instance-hez. Itt is lesz olyan, amit majd csak később állítunk be. A mostani alkalommal egyedül a `vk::Queue`-kra koncentrálunk.
A grafikus kártya egy hihetetlenül parallelizált eszköz. Ám ennek a kihasználásához adatot kell neki küldeni, és megmondani hogy mit csináljon. Ez a parancs feldolgozás *Queue*-kon keresztül történik, amelyek képesek párhuzamosan több "command" végrehajtására.
A grafikus kártya egy hihetetlenül parallelizált eszköz - ám ennek a kihasználásához adatot kell neki küldeni, és megmondani hogy mit csináljon. Ez a parancs feldolgozás *Queue*-kon keresztül történik, amelyek képesek párhuzamosan több "command" végrehajtására.
!!! note ""
!!! tip ""
Habár egy `vk::Queue` egyszerre több `vk::CommandBuffer` végrehajtására is képes, `vk::CommandBuffer`-eket feldolgozásra küldeni egy `vk::Queue`-nak továbbra is csak egy szálon lehetséges.
Egy `vk::Queue` többféle feladat végrehajtására is képes - legyen az grafikai, általános, adat-átvitel, vagy valami más. A GPU tervezők számunkra a hasonló tulajdonságokkal rendelkező *Queue*-kat úgynevezett *Queue family*-kben teszik elérhetővé.
Egy `vk::Queue` többféle feladat végrehajtására is képes lehet - legyen az grafikai, általános feldolgozás, adat-átvitel, vagy valami más. A GPU tervezők számunkra a hasonló tulajdonságokkal rendelkező *Queue*-kat úgynevezett *Queue family*-kbe csoportosítják.
Válasszunk ki egy grafikai munkát támogató családot (ennek megkötése, hogy adat-átvitelt is támogasson), és abból is **egy***Queue*-t. A mi céljainkhoz ez az egy elég lesz mindenre.
Válasszunk ki egy grafikai munkát támogató családot (ebből már következik, hogy adat-átvitelt is támogat), és abból is **egy***Queue*-t. A mi céljainkhoz ez az egy elég lesz mindenre.
!!! example ""
```cpp
[[nodiscard]] static auto find_graphics_queue_family(
[[nodiscard]]
static auto find_graphics_queue_family(
vk::PhysicalDevice t_physical_device
) -> uint32_t
{
...
...
@@ -188,7 +198,8 @@ Adott minden, hogy a *Device*-t is létrehozzuk.
!!! example ""
```cpp
[[nodiscard]] static auto create_device(const vk::PhysicalDevice t_physical_device)
[[nodiscard]]
static auto create_device(const vk::PhysicalDevice t_physical_device)