From d992d96862ed96844db8347d0d2d65a1975b1a4e Mon Sep 17 00:00:00 2001
From: n0F4x <ggabor2002@gmail.com>
Date: Wed, 12 Jun 2024 14:14:34 +0200
Subject: [PATCH] Proofread lecture 1

---
 docs/lectures/01.md | 183 +++++++++-----------------------------------
 mkdocs.yml          |   1 +
 2 files changed, 37 insertions(+), 147 deletions(-)

diff --git a/docs/lectures/01.md b/docs/lectures/01.md
index 57d4bcd..3344875 100644
--- a/docs/lectures/01.md
+++ b/docs/lectures/01.md
@@ -1,3 +1,7 @@
+!!! info ""
+
+    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!"
 
     ```cpp
-    constexpr vk::ApplicationInfo application_info{};
+    constexpr static vk::ApplicationInfo application_info{
+        .apiVersion = VK_API_VERSION_1_0,
+    };
     ```
 
 !!! info inline end "Vulkan layers"
@@ -67,7 +74,7 @@ Debug-oláshoz beállítünk [egy layer](https://vulkan-tutorial.com/Drawing_a_t
 ??? example "Ezt egy globális változóba szervezzük, mert még később is jól jöhet."
 
     ```cpp
-    const std::vector<std::string> g_layers{
+    const std::vector<const char*> g_layers{
     #ifdef ENGINE_VULKAN_DEBUG
         "VK_LAYER_KHRONOS_validation"
     #endif
@@ -84,18 +91,21 @@ Ezeknél több mindent is beállíthatnánk még az Instance létrehozásához,
 
     ```cpp
     const std::vector<const char*> g_layers{
-    #ifdef ENGINE_VULKAN_DEBUG
+    #ifdef RENDERER_VULKAN_DEBUG
         "VK_LAYER_KHRONOS_validation"
     #endif
     };
 
-    [[nodiscard]] static auto create_instance() -> vk::UniqueInstance
+    [[nodiscard]]
+    auto create_instance() -> vk::UniqueInstance
     {
-        constexpr static vk::ApplicationInfo application_info{};
+        constexpr static vk::ApplicationInfo application_info{
+            .apiVersion = VK_API_VERSION_1_0,
+        };
 
         const vk::InstanceCreateInfo create_info{
-            .pApplicationInfo  = &application_info,
-            .enabledLayerCount = static_cast<uint32_t>(g_layers.size()),
+            .pApplicationInfo    = &application_info,
+            .enabledLayerCount   = static_cast<uint32_t>(g_layers.size()),
             .ppEnabledLayerNames = g_layers.data(),
         };
 
@@ -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
         }
 
         auto ranked_devices_view{
-            physical_devices
-            | std::views::transform([](vk::PhysicalDevice t_physical_device) {
-                switch (t_physical_device.getProperties().deviceType) {
+            physical_devices | std::views::transform([](vk::PhysicalDevice physical_device) {
+                switch (physical_device.getProperties().deviceType) {
                     case vk::PhysicalDeviceType::eDiscreteGpu:
-                        return std::make_pair(t_physical_device, 2);
+                        return std::make_pair(physical_device, 2);
                     case vk::PhysicalDeviceType::eIntegratedGpu:
-                        return std::make_pair(t_physical_device, 1);
-                    default: return std::make_pair(t_physical_device, 0);
+                        return std::make_pair(physical_device, 1);
+                    default: return std::make_pair(physical_device, 0);
                 }
             })
         };
@@ -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)
         -> vk::UniqueDevice
     {
         const vk::DeviceQueueCreateInfo queue_create_info{
@@ -208,125 +219,3 @@ Adott minden, hogy a *Device*-t is létrehozzuk.
 !!! tip ""
 
     A `Renderer`-hez adjuk hozzá az így létrejövő `vk::UniqueDevice`-t, és a kiválasztott `vk::Queue`-t is. (Utóbbi lentebb a végső kódban látható.)
-
-## Elkészült kód
-
-!!! example ""
-
-    ```cpp title="Renderer.hpp"
-    #pragma once
-
-    #include <vulkan/vulkan.hpp>
-
-    class Renderer {
-    public:
-        Renderer();
-
-    private:
-        vk::UniqueInstance m_instance;
-        vk::PhysicalDevice m_physical_device;
-        uint32_t           m_graphics_queue_family;
-        vk::UniqueDevice   m_device;
-        vk::Queue          m_graphics_queue;
-    };
-    ```
-
-    ```cpp title="Renderer.cpp"
-    #include "Renderer.hpp"
-
-    #include <algorithm>
-    #include <ranges>
-    #include <vector>
-
-    const std::vector<const char*> g_layers{
-    #ifdef ENGINE_VULKAN_DEBUG
-        "VK_LAYER_KHRONOS_validation"
-    #endif
-    };
-
-    [[nodiscard]] static auto create_instance() -> vk::UniqueInstance
-    {
-        constexpr static vk::ApplicationInfo application_info{};
-
-        const vk::InstanceCreateInfo create_info{
-            .pApplicationInfo    = &application_info,
-            .enabledLayerCount   = static_cast<uint32_t>(g_layers.size()),
-            .ppEnabledLayerNames = g_layers.data(),
-        };
-
-        return vk::createInstanceUnique(create_info);
-    }
-
-    [[nodiscard]] auto static choose_physical_device(const vk::Instance t_instance)
-        -> vk::PhysicalDevice
-    {
-        const auto physical_devices{ t_instance.enumeratePhysicalDevices() };
-
-        if (std::ranges::empty(physical_devices)) {
-            throw std::runtime_error{ "No Vulkan physical device is available." };
-        }
-
-        auto ranked_devices_view{
-            physical_devices
-            | std::views::transform([](vk::PhysicalDevice t_physical_device) {
-                switch (t_physical_device.getProperties().deviceType) {
-                    case vk::PhysicalDeviceType::eDiscreteGpu:
-                        return std::make_pair(t_physical_device, 2);
-                    case vk::PhysicalDeviceType::eIntegratedGpu:
-                        return std::make_pair(t_physical_device, 1);
-                    default: return std::make_pair(t_physical_device, 0);
-                }
-            })
-        };
-        std::vector ranked_devices(
-            ranked_devices_view.begin(), ranked_devices_view.end()
-        );
-
-        std::ranges::sort(
-            ranked_devices,
-            std::ranges::greater{},
-            &std::pair<vk::PhysicalDevice, int>::second
-        );
-
-        return ranked_devices.front().first;
-    }
-
-    [[nodiscard]] auto static find_graphics_queue_family(
-        const vk::PhysicalDevice t_physical_device
-    ) -> uint32_t
-    {
-        uint32_t index{};
-        for (const auto& properties : t_physical_device.getQueueFamilyProperties())
-        {
-            if (properties.queueFlags & vk::QueueFlagBits::eGraphics) {
-                return index;
-            }
-            index++;
-        }
-        throw std::runtime_error{ "Could not find graphics queue family" };
-    }
-
-    [[nodiscard]] auto static create_device(const vk::PhysicalDevice t_physical_device)
-        -> vk::UniqueDevice
-    {
-        const vk::DeviceQueueCreateInfo queue_create_info{
-            .queueFamilyIndex = find_graphics_queue_family(t_physical_device),
-            .queueCount       = 1,
-        };
-
-        vk::DeviceCreateInfo device_create_info{
-            .queueCreateInfoCount = 1,
-            .pQueueCreateInfos    = &queue_create_info,
-        };
-
-        return t_physical_device.createDeviceUnique(device_create_info);
-    }
-
-    Renderer::Renderer()
-        : m_instance{ create_instance() },
-        m_physical_device{ choose_physical_device(*m_instance) },
-        m_graphics_queue_family{ find_graphics_queue_family(m_physical_device) },
-        m_device{ create_device(m_physical_device) },
-        m_graphics_queue{ m_device->getQueue(m_graphics_queue_family, 0) }
-    {}
-    ```
diff --git a/mkdocs.yml b/mkdocs.yml
index 626d863..026eecd 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -47,4 +47,5 @@ markdown_extensions:
   - pymdownx.tabbed:
       alternate_style: true
 nav:
+  - index.md
   - 1. lecke: lectures/01.md
-- 
GitLab