(六) vulkan1 - Drawing a triangle
vulkan官方初步教程vulkan-tutorial.com
Development environment
Ubuntu:不必按照教程中linux来,直接按照window vulkan sdk来
The SDK can be downloaded from the LunarG website:https://vulkan.lunarg.com/sdk/home#linux
不过,只支持ubuntu20.04 / 22.04,执行四条命令
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字节码
有了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创建窗口
继续接受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模式,尽可能地“打印”/检查出潜在的错误;发布时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++的概念类似
百度翻译:例子; 事例; 实例;
我喜欢取第一个概念,转述为创建一个“例子”(应用)并告知要求和用途

前面获取了是否有验证层,有就 “使能调试检查”

一切都是挺自然的事情,正常写应用的思维。(也许痛苦还没有开始)
输出
[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创建的窗口上绘制三角形,自然就是获取窗口的“画板”surface

Physical devices (and Queue families)
枚举获取图形卡设备,这里有个“Queue families”概念,以后接触多了应该就会知道是什么了,现在保留疑问。

Logical device
直译是“逻辑设备”
其实可以看instance(Vulkan API's instance)来联想,就是Physical device‘s instance
创建一个逻辑上的设备(应用),同时创建了两个队列graphicsQueue、presentQueue
看名字留个印象,后面慢慢了解

------------------------------------------------------------------------------------------------------------------
后面的一些概念,在没有大致运行框架的概念下,比较难理解。后续慢慢了解、慢慢理解
------------------------------------------------------------------------------------------------------------------
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,所以需要创建,需要前面的(swap chain)framebuffer的desc描述


其他

看名字就可以理解,待后续了解在框架中的位置
绘制

...
...
...
待后续慢慢了解