图形管线
图形管线是一系列将我们提交的顶点和纹理转换为渲染目标上的像素的操作。它的简化过程如下:

- input assembler 获取顶点数据
- vertex shader 对每个顶点进行模型空间到屏幕空间的变换
- tessellation shader 根据一定的规则对几何图形进行细分,从而提高网格质量
- geometry shader 可以以图元为单位处理几何图形,它可以剔除图元、输出图元,与 tessellation shader 相似,但现在已经不推荐使用
- rasterization 阶段将图元分成片元,这一阶段会执行深度测试
- fragment shader 对每一个未丢弃的片元进行处理,确定哪些片元写入帧缓冲
- color blending 阶段对写入帧缓冲的同一像素位置的不同片段进行混合
绿色标识的是固定功能阶段,固定功能阶段允许通过参数对处理过程进行一定程度的配置
橙色标识的是可编程阶段,允许将自己的代码加载到显卡
相关概念
Instance
PhysicalDevice、Device
QueueFamily、Queue
Surface、Swapchain
CommandPool、CommandBuffer
Semaphore、Fence:
- Semaphore 用于 GPU-GPU 同步
- Fence 用于 CPU-GPU 同步,有
waitForFences函数
Image、ImageView
Shader
Pipeline、ShaderModule
简要流程
前置工作:
Create Window:调用 GLFW 相关函数
Create Instance:需要填入需要的 Layers、Extensions,得到
vk::UniqueInstanceCreate Surface:调用 GLFW 相关函数,得到
vk::UniqueSurfaceKHRSelect GPU:选择一个合适的
vk::PhysicalDevice和vk::QueueFamily,可能要求它必须可以 Present、支持交换链等Create Device:根据选择的
vk::PhysicalDevice和vk::QueueFamily创建vk::UniqueDevice和一些vk::QueueCreate Swapchain:
- 根据
vk::UniqueDevic和窗口的 frame buffer 大小创建一个vk::UniqueSwapchainKHR - 从
vk::UniqueSwapchainKHR中获取足够数量(3 个)的vk::Image - 每个
vk::Image创建一个vk::UniqueImageView - 每个
vk::Image创建一个vk::Semaphore,用来同步“可以呈现”
- 根据
Create Render Sync:
- 创建 1 个
vk::UniqueCommandPool - 用 Command Pool 创建 3 个
vk::CommandBuffer,用于写入命令,每个vk::UniqueImageView对应一个 - 每个 Command Buffer 创建 1 个
vk::UniqueSemaphore,用来同步“可以执行渲染指令” - 每个 Command Buffer 创建 1 个
vk::UniqueFence,用来同步“渲染指令已经执行完成”,初始设置为 signaled
- 创建 1 个
Create Shader:读取 spirv 二进制文件,创建 vertex 和 fragment 两个
vk::UniqueShaderEXT
主循环:
- Acquire Render Target:
- 等待当前帧对应的
vk::CommandBuffer的“渲染指令已经执行完成” Fence 信号(阻塞) - 获取下一个
vk::Image和对应的vk::ImageView,当它准备完成时(即不会阻塞 CPU,而是异步等待),会将当前帧对应的vk::CommandBuffer的“可以执行渲染指令” Semaphore 信号置为 signaled - 如果 Vulkan 表示需要重建 Swapchain,那么就重建,跳过下面的步骤
- 重置“渲染指令已经执行完成” Fence 信号
- 等待当前帧对应的
- Begin Frame:开启当前帧对应
vk::CommandBuffer的录制- Transition For Render:创建
vk::ImageMemoryBarrier2来转换对应vk::Image的 Layout(Undefined 到 ColorAttachmentOptimal) - Render:
- 渲染指令开始
- 将创建的
vk::UniqueShaderEXT绑定到vk::CommandBuffer中 - 渲染
- 渲染指令结束
- Transition For Present:转换 Layout(ColorAttachmentOptimal 到 PresentSrcKHR)
- Transition For Render:创建
- Submit And Present:
- 结束录制
- 将
vk::CommandBuffer提交给vk::CommandQueue(异步):- 提交
- 执行
- 当执行到“写入颜色缓冲区”这一步时,等待当前
vk::CommandBuffer的“可以执行渲染指令” Semaphore 信号 - 完成“写入颜色缓冲区”这一步后,触发当前
vk::Image的“可以呈现” Semaphore 信号 - 继续执行
- 全部执行完成后,触发当前
vk::CommandBuffer的“渲染指令已经执行完成” Fence 信号
- 呈现(异步):
- 等待当前
vk::Image的“可以呈现” Semaphore 信号 - 呈现
- 如果错误,那么可能需要重建 Swapchain,此时进行重建
- 等待当前