Vulkan 是一套分层、显式、多核友好、跨平台的现代图形与计算 API,核心设计目标是低开销、高可控、并行化,相比 OpenGL/D3D11 更贴近现代 GPU 硬件模型。
整体分层架构(自上而下)
Vulkan 采用清晰的五层栈式结构,每层职责明确、隔离性强:
应用层(Application)
- 开发者业务代码,直接调用 Vulkan API。
- 负责:实例 / 设备创建、资源管理、命令录制、渲染循环、呈现(Presentation)。
Vulkan 加载器(Loader)
- 系统级库(
vulkan-1.dll/libvulkan.so),负责:- 枚举并加载ICD 驱动(厂商硬件驱动)。
- 管理Layer 插件链(验证、调试、性能分析)。
- 函数分发:将应用调用路由到对应 Layer / 驱动。
可选层(Layers,开发 / 调试用)
- 可动态插入加载器与驱动之间,发布时可禁用以零开销。
- 常用层:
- 验证层(Validation):检查参数错误、内存泄漏、同步错误。
- 调试层(Debug):日志、回调、性能标记。
- 追踪 / 捕获层:如 RenderDoc、Nsight。
驱动层(ICD,Installable Client Driver)
- GPU 厂商实现(NVIDIA/AMD/Intel/ARM),直接管理硬件。
- 职责:
- 解析 Vulkan 对象(Pipeline/Buffer/Image)。
- 转换命令缓冲区为 GPU 硬件指令。
- 硬件调度、中断处理、电源管理。
硬件层(GPU)
- 现代 GPU 核心单元:
- 计算单元(CU/SM):顶点 / 片段 / 计算着色器执行。
- 固定功能管线:光栅化、深度 / 模板测试、混合。
- 显存与控制器:设备本地显存、主机可见显存。
- 显示输出:扫描线、显示引擎、帧缓冲。
Vulkan 分层架构图
应用程序 (Application) ↓ Vulkan 加载器 (Loader) ↓ 验证层/工具层 (Validation Layers) ↓ 驱动程序 (ICD) ↓ GPU 硬件 (Hardware)核心对象模型(显式、可分发)
Vulkan 以对象化设计管理所有资源与状态,对象分为 ** 可分发(Dispatchable)与非分发(Non-dispatchable)** 两类。
1. 实例(VkInstance)
- 整个 Vulkan 环境的根对象,全局唯一。
- 作用:枚举物理设备、创建调试回调、管理层 / 扩展。
2. 物理设备(VkPhysicalDevice)
- 代表系统中真实 GPU(可能多个)。
- 只读属性:显存大小、队列族、支持的扩展、格式能力。
3. 逻辑设备(VkDevice)
- 应用与物理设备的逻辑连接,是多数操作的上下文。
- 可指定队列创建、启用扩展、分配内存。
4. 队列(VkQueue)与队列族(Queue Family)
- GPU 工作的执行单元,完全并行。
- 队列族类型:
- 图形(GRAPHICS):渲染、管线操作。
- 计算(COMPUTE):通用计算、GPGPU。
- 传输(TRANSFER):拷贝、上传 / 下载。
- 呈现(PRESENT):显示到屏幕(WSI)。
- 一个设备可创建多个同类型队列,支持多线程并行提交。
5. 命令缓冲区(VkCommandBuffer)
- Vulkan核心:GPU 指令的录制容器。
- 流程:分配→录制(渲染 / 计算命令)→提交到队列→执行。
- 支持多线程并行录制(每个线程独立命令缓冲),CPU 开销极低。
6. 管线(Pipeline)
- 分为图形管线(Graphics Pipeline)与计算管线(Compute Pipeline),均为不可变、预编译对象。
- 图形管线阶段:
- 顶点输入 → 顶点着色器 → 光栅化 → 片段着色器 → 深度 / 模板 → 混合 → 帧缓冲。
- 管线一次创建、多次使用,避免 OpenGL 频繁状态切换开销。
7. 资源与内存(显式管理)
- 缓冲区(VkBuffer):顶点、索引、Uniform、存储数据。
- 图像(VkImage):纹理、渲染目标、深度缓冲。
- 内存(VkDeviceMemory):完全显式分配 / 绑定,无隐式内存管理。
- 内存堆:设备本地(VRAM)、主机可见(CPU 可访问)、主机本地(RAM)。
- 描述符集(DescriptorSet):Shader 访问资源的绑定集合(纹理、Uniform 等),显式绑定、高效复用。
8. 渲染通道与帧缓冲(RenderPass + Framebuffer)
- RenderPass:定义渲染流程的子通道(Subpass)、依赖、附件(颜色 / 深度)。
- Framebuffer:绑定具体图像视图,作为 RenderPass 的渲染目标。
- 优势:硬件级渲染优化(如瓦片渲染、子通道合并)。
9. 窗口系统集成(WSI)
- 表面(VkSurfaceKHR):本地窗口的 Vulkan 抽象。
- 交换链(VkSwapchainKHR):一组可呈现图像,处理双缓冲 / 三缓冲、显示同步(V-Sync)。
核心对象关系图
VkInstance ├─ VkPhysicalDevice (GPU) │ └─ VkDevice (逻辑设备) │ ├─ VkQueue (Graphics/Compute/Transfer) │ ├─ VkCommandPool → VkCommandBuffer │ ├─ VkPipeline (Graphics/Compute) │ ├─ VkPipelineLayout │ ├─ VkDescriptorPool → VkDescriptorSet │ ├─ VkBuffer + VkDeviceMemory │ ├─ VkImage + VkDeviceMemory → VkImageView │ ├─ VkRenderPass → VkFramebuffer │ └─ VkSwapchainKHR (WSI) └─ VkSurfaceKHR (窗口)执行模型(并行、异步、显式同步)
多线程友好
- 命令缓冲区可并行录制(多线程互不干扰)。
- 队列提交完全异步,CPU 无需等待 GPU。
- 无全局状态锁,多核 CPU 利用率接近 100%。
显式同步(无隐式屏障)
- 必须手动使用 ** 栅栏(Fence)、信号量(Semaphore)、事件(Event)、内存屏障(Barrier)** 控制依赖。
- 示例:渲染完成 → 信号量 → 呈现;或 传输完成 → 内存屏障 → 着色器读取。
- 代价:开发更复杂;收益:无冗余同步、性能可预测。
与 OpenGL/D3D11 的核心差异
| 特性 | Vulkan | OpenGL/D3D11 |
|---|---|---|
| 控制粒度 | 显式、细粒度(内存 / 同步 / 状态) | 隐式、粗粒度(驱动管理) |
| CPU 开销 | 极低(无状态校验、多线程) | 高(单线程、频繁状态切换) |
| 多线程 | 原生支持(并行录制 / 提交) | 有限支持(多线程渲染困难) |
| 内存管理 | 完全显式(分配 / 绑定 / 释放) | 隐式(驱动缓存 / 回收) |
| 管线 | 预编译、不可变、一次创建多次使用 | 动态状态切换(频繁开销) |
| 跨平台 | 统一 API(Windows/Linux/Android/macOS) | OpenGL(桌面)/GLES(移动)分离 |
完整标准渲染流程(线性步骤)
初始化阶段
- 创建
VkInstance→ 启用扩展 / 验证层 - 枚举
PhysicalDevice→ 筛选合规 GPU - 选定队列族 → 创建
VkDevice + VkQueue
窗口与渲染目标
- 创建
VkSurface→ 创建Swapchain - 获取 Swapchain Image → 新建
ImageView - 配置
RenderPass→ 创建Framebuffer
资源与管线准备
- 编写 SPIR-V 着色器
- 创建
PipelineLayout→ 构建GraphicsPipeline - 分配描述符池 / 布局 → 绑定资源到
DescriptorSet - 创建
CommandPool→ 预分配命令缓冲区
每帧循环(核心)
获取交换链可用图像索引:vkAcquireNextImage
重置 / 录制CommandBuffer
vkBeginCommandBuffervkCmdBeginRenderPass- 绑定管线、描述符集、顶点缓冲
vkCmdDraw绘制- 结束 RenderPass + 结束命令录制
提交命令缓冲区到图形队列:vkQueueSubmit
信号量同步 →vkQueuePresentKHR上屏
销毁阶段逆序释放所有对象,避免内存泄漏
核心对象清单
1. 全局 / 设备基础
| 对象 | 作用 | 核心定位 |
|---|---|---|
VkInstance | 全局根对象、枚举 GPU、加载扩展 | 全局上下文 |
VkPhysicalDevice | 真实硬件 GPU,只读属性 | 硬件信息载体 |
VkDevice | 逻辑设备,业务操作主体 | 设备操作上下文 |
VkQueueFamily | 队列族分类,划分硬件能力 | 硬件能力分组 |
VkQueue | 命令提交执行单元 | GPU 任务执行者 |
2. 渲染 & 管线核心
| 对象 | 作用 |
|---|---|
VkCommandPool | 命令缓冲区内存池,批量分配 Cmd |
VkCommandBuffer | 录制渲染 / 计算 / 传输指令,核心调度单元 |
VkPipeline | 图形 / 计算固定管线(着色器 + 光栅 + 混合等) |
VkPipelineLayout | 管线资源绑定布局 |
VkRenderPass | 定义渲染附件、子通道、硬件依赖 |
VkFramebuffer | 绑定具体颜色 / 深度图像,渲染目标容器 |
3. 资源 & 内存(显式管理)
| 对象 | 作用 |
|---|---|
VkDeviceMemory | 裸显存 / 内存,手动分配绑定 |
VkBuffer | 顶点、索引、UBO、SSBO 通用数据缓冲 |
VkImage | 纹理、渲染目标、深度图 |
VkImageView | Image 视图,Shader 访问纹理的入口 |
VkSampler | 纹理采样规则(过滤、寻址、LOD) |
4. 描述符体系(资源绑定)
| 对象 | 作用 |
|---|---|
VkDescriptorPool | 描述符内存池 |
VkDescriptorSetLayout | 描述符绑定规则(类型、数量) |
VkDescriptorSet | 实际绑定 Buffer/Image/Sampler 给着色器 |
5. 同步 & WSI 窗口
| 对象 | 作用 |
|---|---|
VkSemaphore | 队列间异步同步(GPU-GPU,无阻塞) |
VkFence | GPU-CPU 同步,可等待任务完成 |
VkEvent | 细粒度命令内同步屏障 |
VkSurfaceKHR | 本地窗口句柄抽象 |
VkSwapchainKHR | 交换链,双 / 三缓冲、屏幕呈现 |
四大队列族(硬件能力)
- Graphics:全流程渲染、RenderPass、绘制指令
- Compute:通用 GPGPU、并行计算、离线处理
- Transfer:纯内存拷贝、上传下载,低功耗
- Present:屏幕显示输出(WSI 专属)
Vulkan 核心特性
- 全显式:内存、同步、状态全手动,零驱动隐式开销
- 多线程:Cmd 多线程并行录制,队列多提交
- 硬件贴合:API 映射 GPU 物理单元,性能拉满
- 分层设计:验证层独立,发布可完全移除
- 内存分离:设备本地 VRAM / 主机内存严格区分
总结
- 显式优于隐式:所有状态、资源、同步必须明确指定,消除驱动黑盒开销。
- 并行化优先:为多核 CPU 与多队列 GPU 原生设计,线性扩展性能。
- 贴近硬件:API 模型与 GPU 硬件模型高度一致,无冗余抽象层。
- 跨平台统一:一套 API 覆盖桌面、移动、嵌入式,减少移植成本。