Vulkan初始化过程(硬件视角)

OpenTK 2026-07-08 14:23:56

整体执行位置概览

┌─────────────────────────────────────────────────────────────────────────────┐
│                       CPU vs GPU 执行分布                                   │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  CPU 执行 (应用程序代码)              GPU 执行 (硬件处理)                   │
│  ════════════════════════════════      ════════════════════════════════      │
│                                                                             │
│  ① createInstance()         CPU       (仅创建软件对象,GPU无感知)          │
│  ② setupDebugMessenger()    CPU       (仅设置回调,GPU无感知)              │
│  ③ createSurface()          CPU       (操作系统层面,GPU无感知)            │
│  ④ pickPhysicalDevice()     CPU       (查询GPU信息,GPU响应查询)           │
│  ⑤ createLogicalDevice()    CPU       (创建软件接口,GPU记录状态)          │
│  ⑥ createSwapChain()        CPU       (准备显示资源,GPU分配内存)          │
│  ⑦ createImageViews()       CPU       (创建视图对象,GPU无感知)            │
│  ⑧ createRenderPass()       CPU       (定义渲染流程,GPU无感知)            │
│  ⑨ createGraphicsPipeline() CPU       (编译着色器,GPU准备硬件状态)        │
│  ⑩ createFramebuffers()     CPU       (绑定资源,GPU无感知)                │
│  ⑪ createCommandPool()      CPU       (分配内存,GPU无感知)                │
│  ⑫ createCommandBuffers()   CPU       (分配内存,GPU无感知)                │
│  ⑬ createSyncObjects()      CPU       (创建同步对象,GPU无感知)            │
│                                                                             │
│  主循环: drawFrame()         CPU+GPU   (CPU提交命令,GPU执行渲染)          │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

详细执行流程(硬件视角)

让我用更直观的方式展示每一步在计算机系统中发生了什么:

┌─────────────────────────────────────────────────────────────────────────────────┐
│                          完整的硬件执行流程                                      │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  ┌────────────────────────────────────────────────────────────────────────┐    │
│  │                         CPU 端 (主程序)                                │    │
│  ├────────────────────────────────────────────────────────────────────────┤    │
│  │                                                                        │    │
│  │  ① createInstance()                                                    │    │
│  │     ├─► CPU执行: 创建VkInstance对象                                   │    │
│  │     ├─► CPU执行: 调用Vulkan驱动(DLL/so)加载                           │    │
│  │     ├─► CPU执行: 验证层配置在CPU内存                                  │    │
│  │     └─► GPU状态: 无 (只是建立通信通道)                               │    │
│  │                                                                        │    │
│  │  ② setupDebugMessenger()                                              │    │
│  │     ├─► CPU执行: 注册回调函数到CPU内存                               │    │
│  │     └─► GPU状态: 无                                                   │    │
│  │                                                                        │    │
│  │  ③ createSurface()                                                    │    │
│  │     ├─► CPU执行: 调用操作系统API (Win32/XCB/Wayland)                 │    │
│  │     ├─► CPU执行: 操作系统创建窗口缓冲区                              │    │
│  │     └─► GPU状态: 无                                                   │    │
│  │                                                                        │    │
│  │  ④ pickPhysicalDevice()                                               │    │
│  │     ├─► CPU执行: vkEnumeratePhysicalDevices()                        │    │
│  │     ├─► CPU→GPU: 查询GPU信息 (PCIe总线通信)                          │    │
│  │     ├─► GPU→CPU: 返回设备信息 (设备ID、特性等)                       │    │
│  │     └─► CPU执行: 选择合适GPU并记录在CPU内存                          │    │
│  │                                                                        │    │
│  │  ⑤ createLogicalDevice()                                              │    │
│  │     ├─► CPU执行: 创建VkDevice对象 (CPU内存)                          │    │
│  │     ├─► CPU→GPU: 通知GPU创建设备上下文 (通过驱动)                   │    │
│  │     ├─► CPU→GPU: 分配队列资源 (GPU调度器)                            │    │
│  │     └─► GPU执行: 记录设备状态、准备队列                              │    │
│  │                                                                        │    │
│  │  ⑥ createSwapChain()                                                  │    │
│  │     ├─► CPU执行: 调用Vulkan交换链创建                                │    │
│  │     ├─► CPU→GPU: 请求分配显示缓冲区 (GPU显存)                        │    │
│  │     ├─► GPU执行: 在显存中分配2-3个图像缓冲区                         │    │
│  │     ├─► CPU→GPU: 建立显示控制器连接                                  │    │
│  │     └─► GPU执行: 准备显示管道                                        │    │
│  │                                                                        │    │
│  │  ⑦ createImageViews()                                                 │    │
│  │     ├─► CPU执行: 创建VkImageView对象 (CPU内存)                       │    │
│  │     ├─► CPU→GPU: 告诉GPU如何解释图像数据                             │    │
│  │     └─► GPU执行: 记录视图描述符                                      │    │
│  │                                                                        │    │
│  │  ⑧ createRenderPass()                                                 │    │
│  │     ├─► CPU执行: 创建VkRenderPass对象 (CPU内存)                      │    │
│  │     ├─► CPU执行: 定义渲染流程 (加载/存储/布局转换)                   │    │
│  │     └─► GPU状态: 无 (只是元数据定义)                                 │    │
│  │                                                                        │    │
│  │  ⑨ createGraphicsPipeline()                                           │    │
│  │     ├─► CPU执行: 从硬盘读取SPIR-V着色器 (磁盘→内存)                  │    │
│  │     ├─► CPU执行: 创建VkShaderModule (CPU内存)                        │    │
│  │     ├─► CPU→GPU: 上传着色器代码到GPU (PCIe传输)                      │    │
│  │     ├─► GPU执行: 编译着色器为GPU原生指令 (驱动编译)                  │    │
│  │     ├─► GPU执行: 配置硬件状态 (光栅化器、混合器、深度测试等)         │    │
│  │     └─► GPU执行: 将管线配置写入GPU寄存器                             │    │
│  │                                                                        │    │
│  │  ⑩ createFramebuffers()                                               │    │
│  │     ├─► CPU执行: 创建VkFramebuffer对象 (CPU内存)                     │    │
│  │     ├─► CPU→GPU: 绑定图像视图到渲染通道                              │    │
│  │     └─► GPU执行: 记录帧缓冲配置                                      │    │
│  │                                                                        │    │
│  │  ⑪ createCommandPool()                                                │    │
│  │     ├─► CPU执行: 在CPU内存分配命令池管理结构                         │    │
│  │     ├─► CPU→GPU: 请求GPU端命令缓冲区内存 (显存或系统内存)            │    │
│  │     └─► GPU执行: 准备命令缓冲区存储区域                              │    │
│  │                                                                        │    │
│  │  ⑫ createCommandBuffers()                                             │    │
│  │     ├─► CPU执行: 分配VkCommandBuffer对象                             │    │
│  │     ├─► CPU→GPU: 分配GPU可访问的命令缓冲区内存                       │    │
│  │     └─► GPU状态: 准备好接收命令                                      │    │
│  │                                                                        │    │
│  │  ⑬ createSyncObjects()                                                │    │
│  │     ├─► CPU执行: 创建信号量和栅栏对象 (CPU内存)                      │    │
│  │     ├─► CPU→GPU: 创建GPU端同步对象 (GPU调度器)                       │    │
│  │     └─► GPU执行: 准备同步机制                                        │    │
│  │                                                                        │    │
│  └────────────────────────────────────────────────────────────────────────┘    │
│                                    │                                            │
│                                    ▼                                            │
│  ┌────────────────────────────────────────────────────────────────────────┐    │
│  │              主循环: drawFrame() (每一帧)                              │    │
│  ├────────────────────────────────────────────────────────────────────────┤    │
│  │                                                                        │    │
│  │  1. vkWaitForFences()                                                 │    │
│  │     ├─► CPU执行: 检查栅栏状态 (CPU轮询或等待)                        │    │
│  │     ├─► GPU→CPU: 通知栅栏已触发 (上一帧完成)                         │    │
│  │     └─► CPU继续: 确认可以开始新帧                                    │    │
│  │                                                                        │    │
│  │  2. vkAcquireNextImageKHR()                                           │    │
│  │     ├─► CPU→GPU: 请求获取下一个交换链图像                            │    │
│  │     ├─► GPU执行: 检查显示控制器状态                                  │    │
│  │     ├─► GPU执行: 选择可用图像                                        │    │
│  │     ├─► GPU→CPU: 返回图像索引                                        │    │
│  │     └─► CPU执行: 获取到图像索引                                      │    │
│  │                                                                        │    │
│  │  3. vkResetCommandBuffer() + recordCommandBuffer()                    │    │
│  │     ├─► CPU执行: 重置命令缓冲区                                      │    │
│  │     ├─► CPU执行: 录制命令到CPU内存                                   │    │
│  │     │   ├─► vkCmdBeginRenderPass()  (CPU写入命令)                   │    │
│  │     │   ├─► vkCmdBindPipeline()     (CPU写入命令)                   │    │
│  │     │   ├─► vkCmdSetViewport()      (CPU写入命令)                   │    │
│  │     │   ├─► vkCmdDraw()             (CPU写入命令)                   │    │
│  │     │   └─► vkCmdEndRenderPass()    (CPU写入命令)                   │    │
│  │     ├─► CPU→GPU: 将命令缓冲区上传到GPU可访问内存                     │    │
│  │     └─► GPU执行: 命令缓冲区就绪 (等待提交)                          │    │
│  │                                                                        │    │
│  │  4. vkQueueSubmit()                                                   │    │
│  │     ├─► CPU执行: 构建提交信息                                        │    │
│  │     ├─► CPU→GPU: 将命令缓冲区提交到图形队列                          │    │
│  │     ├─► GPU执行: 调度器接收命令                                      │    │
│  │     ├─► GPU执行: 等待信号量 (图像可用)                              │    │
│  │     ├─► GPU执行: 开始执行命令                                       │    │
│  │     │   ├─► 顶点着色器执行 (GPU核心)                                │    │
│  │     │   ├─► 光栅化 (GPU硬件)                                        │    │
│  │     │   ├─► 片段着色器执行 (GPU核心)                                │    │
│  │     │   └─► 颜色混合/写入帧缓冲 (GPU硬件)                           │    │
│  │     ├─► GPU执行: 完成渲染后触发信号量                               │    │
│  │     └─► GPU执行: 完成后触发栅栏                                     │    │
│  │                                                                        │    │
│  │  5. vkQueuePresentKHR()                                               │    │
│  │     ├─► CPU执行: 提交呈现请求                                        │    │
│  │     ├─► CPU→GPU: 通知显示控制器                                      │    │
│  │     ├─► GPU执行: 等待渲染完成信号量                                  │    │
│  │     ├─► GPU执行: 将图像交给显示控制器                                │    │
│  │     ├─► 显示控制器: 在下一个VBlank读取图像并显示到屏幕               │    │
│  │     └─► GPU→CPU: 返回呈现结果                                        │    │
│  │                                                                        │    │
│  └────────────────────────────────────────────────────────────────────────┘    │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

计算机系统的层次结构

┌─────────────────────────────────────────────────────────────────────────────────┐
│                        完整的系统层次结构                                         │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  用户应用程序 (你的代码)                                                        │
│  ┌─────────────────────────────────────────────────────────────────────┐       │
│  │  HelloTriangleApplication::run()                                    │       │
│  │  ├─► initWindow()    (CPU执行)                                     │       │
│  │  ├─► initVulkan()    (CPU执行, 主要配置)                           │       │
│  │  ├─► mainLoop()      (CPU执行提交, GPU执行渲染)                    │       │
│  │  └─► cleanup()       (CPU执行)                                     │       │
│  └─────────────────────────────────────────────────────────────────────┘       │
│                                    ↓                                             │
│  Vulkan API (驱动层)                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐       │
│  │  Vulkan Loader (vulkan-1.dll / libvulkan.so)                       │       │
│  │  ├─► 验证层 (Validation Layers) - CPU执行                          │       │
│  │  ├─► API调用分发                                                   │       │
│  │  └─► 驱动特定实现                                                  │       │
│  └─────────────────────────────────────────────────────────────────────┘       │
│                                    ↓                                             │
│  GPU驱动 (NVIDIA/AMD/Intel)                                                      │
│  ┌─────────────────────────────────────────────────────────────────────┐       │
│  │  ├─► 命令缓冲区管理 (CPU→GPU传输)                                  │       │
│  │  ├─► 着色器编译 (CPU执行: SPIR-V→GPU原生指令)                     │       │
│  │  ├─► 内存管理 (CPU执行: 分配GPU显存)                              │       │
│  │  └─► 硬件调度 (CPU执行: 提交命令到GPU)                            │       │
│  └─────────────────────────────────────────────────────────────────────┘       │
│                                    ↓                                             │
│  GPU硬件                                                                        │
│  ┌─────────────────────────────────────────────────────────────────────┐       │
│  │  GPU Core (流处理器/SM/CU)                                          │       │
│  │  ├─► 顶点处理单元                                                  │       │
│  │  ├─► 光栅化单元                                                    │       │
│  │  ├─► 片段处理单元                                                  │       │
│  │  └─► 纹理单元                                                      │       │
│  │                                                                     │       │
│  │  GPU显存 (VRAM)                                                    │       │
│  │  ├─► 交换链图像                                                    │       │
│  │  ├─► 着色器代码                                                    │       │
│  │  ├─► 顶点/索引缓冲                                                 │       │
│  │  └─► 纹理数据                                                      │       │
│  │                                                                     │       │
│  │  显示控制器                                                        │       │
│  │  ├─► 从交换链读取图像                                              │       │
│  │  ├─► 信号处理 (HDMI/DP)                                            │       │
│  │  └─► 发送到显示器                                                  │       │
│  └─────────────────────────────────────────────────────────────────────┘       │
│                                    ↓                                             │
│  显示器                                                                         │
│  ┌─────────────────────────────────────────────────────────────────────┐       │
│  │  显示像素                                                        │       │
│  └─────────────────────────────────────────────────────────────────────┘       │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

内存与数据传输流程

┌─────────────────────────────────────────────────────────────────────────────────┐
│                        数据流动路径                                               │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  硬盘 (磁盘)                                                                    │
│  ┌──────────────────────┐                                                       │
│  │ 着色器 .spv文件      │                                                       │
│  └──────────┬───────────┘                                                       │
│             │ fstream::read() (CPU执行)                                         │
│             ▼                                                                   │
│  系统内存 (RAM)                                                                 │
│  ┌──────────────────────┐                                                       │
│  │ 着色器字节数组       │ ← createShaderModule() 读取到系统内存               │
│  │ SPIR-V代码           │                                                       │
│  └──────────┬───────────┘                                                       │
│             │ vkCreateShaderModule() (CPU执行)                                  │
│             │ PCIe总线传输 (CPU→GPU)                                            │
│             ▼                                                                   │
│  GPU显存 (VRAM)                                                                 │
│  ┌──────────────────────┐                                                       │
│  │ 编译后的着色器       │ ← GPU驱动编译为原生指令                              │
│  │ GPU原生指令          │                                                       │
│  └──────────┬───────────┘                                                       │
│             │ GPU执行                                                           │
│             ▼                                                                   │
│  GPU核心执行                                                                   │
│  ┌──────────────────────┐                                                       │
│  │ 着色器核心执行       │                                                       │
│  │ 光栅化、混合等       │                                                       │
│  └──────────┬───────────┘                                                       │
│             │ 写入帧缓冲                                                        │
│             ▼                                                                   │
│  GPU显存中的交换链图像                                                         │
│  ┌──────────────────────┐                                                       │
│  │ 渲染结果 (像素数据)   │                                                       │
│  └──────────┬───────────┘                                                       │
│             │ 显示控制器读取                                                    │
│             ▼                                                                   │
│  显示信号 (HDMI/DP)                                                             │
│  ┌──────────────────────┐                                                       │
│  │ 视频信号输出         │                                                       │
│  └──────────┬───────────┘                                                       │
│             │                                                                   │
│             ▼                                                                   │
│  显示器屏幕                                                                     │
│  ┌──────────────────────┐                                                       │
│  │ 显示三角形           │                                                       │
│  └──────────────────────┘                                                       │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

CPU和GPU的并行执行

┌─────────────────────────────────────────────────────────────────────────────────┐
│                      CPU和GPU并行执行时间线                                      │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  时间 →                                                                        │
│                                                                                 │
│  CPU线程:                                                                      │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │ 初始化阶段 (主要CPU)                                                   │   │
│  │ ├─► createInstance()    ████                                           │   │
│  │ ├─► createSurface()     ███                                            │   │
│  │ ├─► pickPhysicalDevice() ██████  (查询GPU)                           │   │
│  │ ├─► createDevice()      ████                                           │   │
│  │ ├─► createSwapChain()   ████  (分配GPU内存)                          │   │
│  │ ├─► createPipeline()    ████████  (上传着色器到GPU)                  │   │
│  │ └─► ...                                                               │   │
│  │                                                                        │   │
│  │ 渲染循环 (每帧)                                                       │   │
│  │ ├─► vkAcquireImage()    ██  (等待GPU)                               │   │
│  │ ├─► recordCommands()    ████  (CPU录制)                              │   │
│  │ ├─► vkQueueSubmit()     ██  (提交到GPU)                             │   │
│  │ ├─► vkQueuePresent()    ██  (等待GPU)                               │   │
│  │ └─► 返回                                                        │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
│                                    │                                             │
│                                    │ 提交命令                                    │
│                                    ▼                                             │
│  GPU执行:                                                                       │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │ 等待命令...              (GPU空闲)                                     │   │
│  │                                                                        │   │
│  │ 收到命令开始执行                                                      │   │
│  │ ├─► 等待图像可用        ██                                            │   │
│  │ ├─► 执行顶点着色器      ████████                                      │   │
│  │ ├─► 光栅化              ██████                                        │   │
│  │ ├─► 执行片段着色器      ████████                                      │   │
│  │ ├─► 混合/写入           ████                                          │   │
│  │ ├─► 呈现到显示          ████                                          │   │
│  │ └─► 触发栅栏            █                                             │   │
│  │                                                                        │   │
│  │ 继续下一帧...                                                          │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
│                                                                                 │
│  注意:                                                                          │
│  1. CPU提交命令后可以立即处理其他事情 (异步)                                   │
│  2. GPU执行时CPU可以同时录制下一帧的命令                                       │
│  3. 通过信号量和栅栏实现CPU-GPU同步                                            │
│  4. 双重/三重缓冲允许CPU和GPU并行工作                                          │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

关键概念总结

┌─────────────────────────────────────────────────────────────────────────────────┐
│                         关键概念总结                                              │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│  1. 哪些在CPU执行?                                                             │
│     ├─► 所有Vulkan API调用 (vkCreate*, vkAllocate*, vkGet*)                   │
│     ├─► 创建和管理对象 (VkInstance, VkDevice, VkPipeline等)                   │
│     ├─► 录制命令缓冲区 (vkCmd*)                                               │
│     ├─► 提交命令到GPU (vkQueueSubmit)                                         │
│     ├─► 读取文件 (着色器、纹理、模型数据)                                     │
│     └─► 窗口管理 (GLFW、操作系统API)                                          │
│                                                                                 │
│  2. 哪些在GPU执行?                                                             │
│     ├─► 顶点着色器执行                                                         │
│     ├─► 细分和几何着色器执行                                                   │
│     ├─► 光栅化                                                                 │
│     ├─► 片段着色器执行                                                         │
│     ├─► 深度/模板测试                                                          │
│     ├─► 颜色混合                                                               │
│     ├─► 计算着色器执行                                                         │
│     └─► 呈现到显示                                                             │
│                                                                                 │
│  3. 哪些涉及CPU→GPU通信?                                                       │
│     ├─► 创建交换链 (分配GPU显存)                                               │
│     ├─► 创建着色器模块 (上传着色器代码)                                        │
│     ├─► 创建缓冲区/图像 (分配GPU资源)                                          │
│     ├─► vkQueueSubmit (传输命令缓冲区)                                         │
│     ├─► vkQueuePresent (通知显示控制器)                                        │
│     └─► 同步操作 (信号量/栅栏状态查询)                                         │
│                                                                                 │
│  4. 哪些数据在GPU显存中?                                                       │
│     ├─► 交换链图像 (2-3个帧缓冲)                                               │
│     ├─► 编译后的着色器代码                                                     │
│     ├─► 顶点/索引缓冲区                                                        │
│     ├─► 纹理图像                                                               │
│     ├─► Uniform缓冲区 (常量数据)                                               │
│     └─► 命令缓冲区                                                             │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

 

...全文
191 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

4

社区成员

发帖
与我相关
我的任务
社区描述
openTK、OpenGL、WebGL技术学习交流
图形渲染c#程序人生 技术论坛(原bbs) 广东省·深圳市
社区管理员
  • 亿只小灿灿
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧