
Python – 29. časť Vulkan prakticky
Túto časť seriálu venujeme extrémne stručnému opisu praktickej aplikácie, v rámci ktorej využijeme funkcionalitu API Vulkan na vykreslenie jednoduchej scény. Hneď v úvode zopakujeme, že jazyk Python z pohľadu výkonu v žiadnom prípade nesiaha na jednoznačného lídra, ktorým je jazyk C. Efektivitu programového kódu takisto nemožno prehnane vyzdvihnúť, pretože Vulkan si v oboch prípadoch vyžaduje oveľa náročnejšiu a hlavne rozsahovo väčšiu prípravu kódu. Čo si však môžeme z tohto článku odniesť, je poznanie, že Python je svojou flexibilitou skutočne bezhraničný a okrem ostatnej funkcionality dokáže bez problémov pracovať s modernými programovacími rozhraniami, medzi ktoré patrí aj API Vulkan.
Príprava prostredia
Na to, aby sme mohli pripraviť a spustiť priloženú vzorovú aplikáciu s názvom PyGLSL v2.0, musíme vykonať minimálne nasledujúce dva kroky:
1. V prípade OS Windows musíme nainštalovať Vulkan SDK, resp. aplikáciu by sa nám mohlo podariť spustiť aj bez inštalácie SDK, a to tak, že z balíka tzv. Runtime komponentov VulkanRT-...-Components.zip (https://vulkan.lunarg.com/sdk/home#windows) skopírujeme súbor vulkan-1.dll do hlavnej zložky aplikácie a následne v rámci prostredia PyCharm doinštalujeme balík vulkan; v prípade OS Linux stačí doinštalovať iba balík vulkan.
2. V prípade OS Windows je súčasťou inštalačného balíka Vulkan SDK aj kompilátor glslc.exe, pomocou ktorého transformujeme GLSL kód shaderov na SPIR-V bytecode; v prípade OS Linux je situácia jemne zložitejšia, pričom treba vykonať postup uvedený na stránke https://github.com/google/shaderc#downloads, resp. skrátene:
git clone https://github.com/google/shaderc shaderc
cd shaderc
./utils/git-sync-deps
mkdir shaderc-build
cd shaderc-build
cmake -GNinja -DCMAKE_BUILD_TYPE=Release ../shaderc
ninja
ctest (nepovinné)
Príprava shaderov
Shadery našej vzorovej aplikácie sa nachádzajú v zložke shaders. Ako vieme, Vulkan požaduje, aby bol kód shaderov transformovaný do formátu SPIR-V. Práve preto sa v spomínanej zložke nachádza 2× kód vertex a 2× kód fragment shadera. Rozdiel medzi nimi je v tom, že kód GLSL je čitateľný a pred jeho použitím ho treba previesť na binárny kód SPIR-V pomocou príkazov:
glslc shader.vert -o vert.spv
glslc shader.frag -o frag.spv
Kód shaderov je triviálny, no čo je dôležité, na zjednodušenie prípravy vzorovej aplikácie je v ňom zahrnutá definícia vrcholov a farieb dvojice trojuholníkov, ktoré sú obsahom našej scény. Vyhneme sa tak nutnosti nadbytočnej prípravy príslušných zásobníkov v rámci zdrojového kódu aplikácie. Túto funkcionalitu si ozrejmíme v nasledujúcej časti seriálu.
Obr. 1 Zjednodušená schéma inicializácie a použitia API Vulkan
Zdrojový kód aplikácie PyGLSL v2.0
Na to, aby naša prvá aplikácia Vulkan fungovala, musíme povinne vykonať prípravu = postupnosť niekoľkých na seba nadväzujúcich krokov. Celý postup je oveľa komplikovanejší ako v prípade API OpenGL (kód aplikácie má 547 riadkov), ale z dôvodov, ktoré sme si uviedli v predošlej časti seriálu, je postup komplexnejší a omnoho viac etablovaný na moderný grafický hardvér.
Drvivú väčšinu kódu sme umiestnili do triedy VulkanApp. Na začiatku definujeme jej atribúty a hneď potom riešime nasledujúce úlohy:
1. Vytvorenie okna GLFW so stanovenou šírkou, výškou a textovým opisom:
glfw.create_window |
in: width, height |
2. Inicializácia API Vulkan:
2.a Vytvorenie izolovanej inštancie API Vulkan |
|
vkCreateInstance |
in: ApplicationInfo, reqExtensions, InstanceCreateInfo |
2.b Vytvorenie WIN surface |
|
glfw.create_window_surface |
in: VkInstance, GLFW okno |
2.c Výber fyzického zariadenia (GPU) |
|
vkEnumeratePhysicalDevices |
in: VkInstance, WIN surface |
2.d Vytvorenie logického zariadenia |
|
vkCreateDevice |
in: Fyzické zariadenie, WIN surface, DeviceQueueCreateInfo, DeviceCreateInfo, PhysicalDeviceFeatures, reqExtensions |
2.e Vytvorenie Swapchain a získanie nevyhnutných informácií o Swapchain |
|
vkCreateSwapchainKHR |
in: VkInstance, WIN surface, Fyzické zariadenie, Logické zariadenie, SwapchainCreateInfo |
vkGetSwapchainImagesKHR |
in: Logické zariadenie, Swapchain |
2.f Vytvorenie zásobníkov na uloženie obrazu |
|
vkCreateImageView |
in: Logické zariadenie, Swapchain, ImageViewCreateInfo |
2.g Vytvorenie RenderPass a Framebuffers |
|
vkCreateRenderPass |
in: Logické zariadenie, Swapchain, RenderPassCreateInfo |
vkCreateFramebuffer |
in: Logické zariadenie, Swapchain, RenderPass, FramebufferCreateInfo |
2.h Vytvorenie shader modulov |
|
vkCreateShaderModule |
in: ShaderModuleCreateInfo, PipelineShaderStageCreateInfo |
2.i Vytvorenie renderovacieho (Graphics) pipeline |
|
vkCreatePipelineLayout, vkCreateGraphicsPipelines |
in: Logické zariadenie, Shader moduly, PipelineVertexInputStateCreateInfo, PipelineInputAssemblyStateCreateInfo, Swapchain, PipelineViewportStateCreateInfo, PipelineRasterizationStateCreateInfo, PipelineMultisampleStateCreateInfo, PipelineColorBlendStateCreateInfo, PipelineLayoutCreateInfo, GraphicsPipelineCreateInfo, RenderPass |
2.j Vytvorenie CommandPool a alokovanie CommandBuffers |
|
vkCreateCommandPool, vkAllocateCommandBuffers |
in: Logické zariadenie, VkInstance, WIN surface, CommandPoolCreateInfo, Swapchain, CommandBufferAllocateInfo, RenderPass, GraphicsPipeline |
2.k Vytvorenie Semaphore |
|
vkCreateSemaphore |
in: Logické zariadenie, SemaphoreCreateInfo |
3. Vykreslenie snímky prebieha v hlavnom programovom cykle mainLoop(), odkiaľ sa volá metóda drawFrame(), ktorá na svoju činnosť využíva logické zariadenie, Swapchain, Semaphore a CommandBuffers. Konkrétne „výkonné“ príkazy sú definované pri alokovaní CommandBuffers:
VkClearValue |
Farba, ktorou sa vypĺňa snímka |
vkBeginCommandBuffer |
BEGIN CommandBuffer |
vkCmdBeginRenderPass |
BEGIN RenderPass |
vkCmdBindPipeline |
Pripojenie Graphics Pipeline |
vkCmdDraw |
Vykreslenie objektov scény |
vkCmdEndRenderPass |
END RenderPass |
vkEndCommandBuffer |
END CommandBuffer |
4. Fáza ukončenia aplikácie je definovaná vo funkcii exit(), kde postupne dôjde k uvoľneniu všetkých alokovaných zdrojov okrem shader modulov, ktoré už boli zrušené.
Obr. 2 Grafický výstup aplikácie PyGLSL v2.0
Marek Sopko
Zobrazit Galériu