(六) vulkan1 - Drawing a triangle
vulkan官方初步教程vulkan-tutorial.com
Development environment
Ubuntu:不必按照教程中l(wèi)inux來,直接按照window vulkan sdk來
The SDK can be downloaded from?the LunarG website:https://vulkan.lunarg.com/sdk/home#linux
不過,只支持ubuntu20.04 / 22.04,執(zhí)行四條命令
wget -qO- https://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo tee /etc/apt/trusted.gpg.d/lunarg.asc
sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-1.3.243-jammy.list https://packages.lunarg.com/vulkan/1.3.243/lunarg-vulkan-1.3.243-jammy.list
sudo apt update
sudo apt install vulkan-sdk
安裝完后glslc也有了
教程還需要GLFW庫,sudo apt install libglfw3-dev
Drawing a triangle
"talk is cheap, show me the code"
????先把代碼運行起來再去學習
直接到https://vulkan-tutorial.com/Drawing_a_triangle/Swap_chain_recreation最后
C++ code?/?Vertex shader?/?Fragment shader,復制出來
????Unlike earlier APIs, shader code in Vulkan has to be specified in a bytecode format as opposed to human-readable syntax like?GLSL?and?HLSL. This bytecode format is called?SPIR-V?and is designed to be used with both Vulkan and OpenCL (both Khronos APIs). It is a format that can be used to write graphics and compute shaders, but we will focus on shaders used in Vulkan's graphics pipelines in this tutorial.
? ? 和OpenGL直接加載shader再在內部編譯不同,vulkan需要SPIR-V字節(jié)碼
????有了glslc就很簡單,無參數命令 glslc shader -o spv
????所以編譯,三條命令:
glslc shader.vert -o vert.spv
glslc shader.frag -o frag.spv
g++ main.cpp -o draw -lvulkan -lglfw

????同時參考https://zhuanlan.zhihu.com/p/430397192【Vulkan從入門到精通】學習
GLFW創(chuàng)建窗口
????繼續(xù)接受QtCreator的調教




? ??
Validation layers
vulkan-tutorial:
? ? vulkan是為了最小化驅動而設計的,這樣就給了用戶最大化的使用能力,同時也帶來了怎么判斷用戶的操作是否正確的問題。
????所以添加了一個可選的東西叫“validation layers”(注意它是什么,看下面)
Common operations in validation layers are:
Checking the values of parameters against the specification to detect misuse
檢查參數是否有被錯誤使用
Tracking creation and destruction of objects to find resource leaks
追蹤資源是否有泄漏
Checking thread safety by tracking the threads that calls originate from
檢查線程安全(vulkan比起opengl,添加了多線程)
Logging every call and its parameters to the standard output
打印每個調用
Tracing Vulkan calls for profiling and replaying
一個簡單的參數檢查示例如下
VkResult vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const VkAllocationCallbacks* pAllocator,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? VkInstance* instance)
{? ? ? ??
? ? ? ? if (pCreateInfo == nullptr || instance == nullptr) {
? ? ? ? ? ? log("Null pointer passed to required parameter!");
? ? ? ? ? ? return VK_ERROR_INITIALIZATION_FAILED;
? ? ? ? }
? ? ? ? return real_vkCreateInstance(pCreateInfo, pAllocator, instance);
}
????這樣就很清楚“validation layers”是什么東西了 (翻譯為“驗證層”也能理解)
????其實就是一種debug和release模式(極端且更接近的是assert斷言)
(所以不用正確翻譯,就直接說是 “使能調試檢查”)
????在編寫代碼時使用debug模式,盡可能地“打印”/檢查出潛在的錯誤;發(fā)布時release模式,去掉多余的調用/封裝/檢查來提高“性能”
????注意是可選項,所以需要檢查SDK是否提供了這樣的驗證層? ??
只是檢查,直接在構造函數中實現

可以看到打印輸出
layer[0] : VK_LAYER_MESA_device_select
layer[1] : VK_LAYER_INTEL_nullhw
layer[2] : VK_LAYER_MESA_overlay
layer[3] : VK_LAYER_LUNARG_gfxreconstruct
layer[4] : VK_LAYER_KHRONOS_validation
Instance
????The very first thing you need to do is initialize the Vulkan library by creating an?instance. ????The instance is the connection between your application and the Vulkan library and creating it involves specifying some details about your application to the driver.
????《Vulkan從入門到精通》翻譯為實例化,和c++的概念類似
????百度翻譯:例子; 事例; 實例;
????我喜歡取第一個概念,轉述為創(chuàng)建一個“例子”(應用)并告知要求和用途

???前面獲取了是否有驗證層,有就?“使能調試檢查”

一切都是挺自然的事情,正常寫應用的思維。(也許痛苦還沒有開始)
輸出
[VERBOSE] validation layer: Searching for ICD drivers named /usr/lib/x86_64-linux-gnu/libvulkan_intel.so
[VERBOSE] validation layer: Searching for ICD drivers named /usr/lib/x86_64-linux-gnu/libvulkan_lvp.so
[VERBOSE] validation layer: Searching for ICD drivers named /usr/lib/x86_64-linux-gnu/libvulkan_radeon.so
[VERBOSE] validation layer: Loading layer library libVkLayer_khronos_validation.so
[VERBOSE] validation layer: Loading layer library libVkLayer_MESA_device_select.so
[VERBOSE] validation layer: Copying old device 0 into new device 0
[VERBOSE] validation layer: Unloading layer library libVkLayer_MESA_device_select.so
[VERBOSE] validation layer: Unloading layer library libVkLayer_khronos_validation.so
至于教程中CreateDebugUtilsMessengerEXT(),在這一個例子中并沒有什么實際作用,可以不加。
Window surface
????要繪畫,就需要有畫板,而這畫板一般被稱為“surface”(還有一個詞叫“canvas”)
????這里要在來自GLFW創(chuàng)建的窗口上繪制三角形,自然就是獲取窗口的“畫板”surface

Physical devices (and Queue families)
????枚舉獲取圖形卡設備,這里有個“Queue families”概念,以后接觸多了應該就會知道是什么了,現在保留疑問。

Logical device
????直譯是“邏輯設備”
????其實可以看instance(Vulkan API's instance)來聯想,就是Physical device‘s instance
????創(chuàng)建一個邏輯上的設備(應用),同時創(chuàng)建了兩個隊列graphicsQueue、presentQueue
????看名字留個印象,后面慢慢了解

------------------------------------------------------------------------------------------------------------------
后面的一些概念,在沒有大致運行框架的概念下,比較難理解。后續(xù)慢慢了解、慢慢理解
------------------------------------------------------------------------------------------------------------------
Swap chain


可以看到,選擇surface format(這里選擇VK_FORMAT_B8G8R8A8_SRGB)、present mode(這里選擇VK_PRESENT_MODE_MAILBOX_KHR?)、extent(width、height)
????(Vulkan does not have the concept of a "default framebuffer")vulkan不提供默認的framebuffer,需要設置,就需要有framebuffer相關的信息,可以表示為framebuffer的desc描述。
?????vulkan使用“swap chain”,使用時會有多個“buffer”,形成一條鏈,用戶到設備進行交換?? ??(第一次接觸,感覺這里應該把swapchainimage挪到下面)
Image views


(swapchainimage挪到這里)
一樣,暫時理解為 image的desc描述
Render passes

????第一次接觸,不理解
Pipeline Shader
????由于已經提前編譯了,直接讀就可以了。

????但也由于已經提前編譯了,就需要設置相關信息。



FrameBuffer
????前面有說,vulkan沒有默認framebuffer,所以需要創(chuàng)建,需要前面的(swap chain)framebuffer的desc描述


其他

????看名字就可以理解,待后續(xù)了解在框架中的位置
繪制

...
...
...
待后續(xù)慢慢了解