news 2026/6/15 21:28:10

[Vulkan 学习之路] 02 - 万物起源:创建 Vulkan 实例 (Instance)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
[Vulkan 学习之路] 02 - 万物起源:创建 Vulkan 实例 (Instance)

上一篇我们成功搭建了环境并弹出了一个黑窗口。今天,我们要正式初始化 Vulkan 库。

在 Vulkan 中,没有什么是“默认”发生的。不同于 OpenGL 的上下文(Context),Vulkan 使用Instance(实例)来存储所有每个应用层面的状态。这是你的应用程序与 Vulkan 库、显卡驱动之间建立连接的桥梁。

核心概念:Vulkan 的“填表”哲学

在开始写代码前,你需要习惯 Vulkan 的编程模式:“填表 -> 提交”

几乎所有的 Vulkan 操作都遵循这个流程:

  1. 定义一个CreateInfo结构体(填表)。

  2. 设置结构体的各种参数(明确你的需求)。

  3. 调用vkCreateXXX函数,把表交给驱动(提交)。

创建 Instance 也不例外。


第一步:填写应用程序信息 (VkApplicationInfo)

首先,我们可以(这是可选的,但推荐做)告诉驱动程序我们的应用叫什么名字,版本是多少。这有助于显卡厂商针对特定的游戏或引擎进行驱动层面的优化。

void createInstance() { // 1. 填写应用信息 VkApplicationInfo appInfo{}; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; // 必须指明结构体类型 appInfo.pApplicationName = "Hello Triangle"; appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); appInfo.pEngineName = "No Engine"; appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); appInfo.apiVersion = VK_API_VERSION_1_0; // 我们使用 Vulkan 1.0 标准 // ... 后续代码 }

注意:在 Vulkan 中,几乎所有的结构体都需要你手动设置sType成员。这是因为 Vulkan 内部为了性能使用void*指针传递结构体,它需要sType来识别这是什么类型的数据。


第二步:获取必要的扩展 (Extensions)

Vulkan 是一个平台无关的 API。这意味着核心的 Vulkan 库根本不知道什么是 "Windows" 或 "窗口"。它只懂图形计算。

要让 Vulkan 能在 Windows 的窗口上画图,我们需要启用扩展 (Extensions)。幸好,GLFW 内置了一个帮助函数,能告诉我们需要哪些扩展。

// ... 接上文 // 获取 GLFW 需要的扩展 (例如 VK_KHR_surface 和 VK_KHR_win32_surface) uint32_t glfwExtensionCount = 0; const char** glfwExtensions; glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);

虽然glfwGetRequiredInstanceExtensions返回的是 C 风格数组,但在后续教程中我们会大量使用std::vector,Vulkan 的很多 count/data 模式很适合转换成 vector。


第三步:填写实例创建信息 (VkInstanceCreateInfo)

这是创建 Instance 过程中最重要的结构体。它告诉 Vulkan 驱动我们需要哪些全局扩展和校验层。

// ... 接上文 // 2. 填写实例创建信息 (这是必须的) VkInstanceCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.pApplicationInfo = &appInfo; // 链接上面的应用信息 // 填入扩展信息 createInfo.enabledExtensionCount = glfwExtensionCount; createInfo.ppEnabledExtensionNames = glfwExtensions; // 暂时不启用校验层 (Validation Layers),下一章会讲,这里先填 0 createInfo.enabledLayerCount = 0;

第四步:创建与清理

终于可以调用vkCreateInstance了。

在 Vulkan 中,创建函数通常返回一个VkResult。如果返回值不是VK_SUCCESS,说明出错了。

同时,我们必须遵循RAII原则(资源获取即初始化),或者是手动管理的原则:如果你 Create 了它,你就必须 Destroy 它。

修改HelloVulkanApp

我们需要在类成员中添加VkInstance变量,并完善initVulkancleanup

class HelloVulkanApp { public: void run() { initWindow(); initVulkan(); mainLoop(); cleanup(); } private: GLFWwindow* window; VkInstance instance; // <--- 新增成员变量 void initVulkan() { createInstance(); } void createInstance() { // 1. 应用信息 VkApplicationInfo appInfo{}; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.pApplicationName = "Hello Triangle"; appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); appInfo.pEngineName = "No Engine"; appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); appInfo.apiVersion = VK_API_VERSION_1_0; // 2. 获取 GLFW 扩展 uint32_t glfwExtensionCount = 0; const char** glfwExtensions; glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); // 3. 实例创建信息 VkInstanceCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.pApplicationInfo = &appInfo; createInfo.enabledExtensionCount = glfwExtensionCount; createInfo.ppEnabledExtensionNames = glfwExtensions; createInfo.enabledLayerCount = 0; // 暂时为 0 // 4. 创建实例 (检查结果) VkResult result = vkCreateInstance(&createInfo, nullptr, &instance); if (result != VK_SUCCESS) { throw std::runtime_error("failed to create instance!"); } } // ... mainLoop 保持不变 ... void cleanup() { // 注意顺序:先销毁 Vulkan 实例,再销毁 GLFW 窗口 vkDestroyInstance(instance, nullptr); // <--- 新增清理代码 glfwDestroyWindow(window); glfwTerminate(); } // ... initWindow 保持不变 ... };

运行与调试

将上述代码整合到你的main.cpp中并运行。

#define GLFW_INCLUDE_VULKAN #include <GLFW/glfw3.h> #include <iostream> #include <stdexcept> #include <cstdlib> const uint32_t WIDTH = 800; const uint32_t HEIGHT = 600; class HelloTriangleApplication { public: void run() { initWindow(); initVulkan(); mainLoop(); cleanup(); } private: GLFWwindow* window; VkInstance instance; void initWindow() { glfwInit(); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr); } void initVulkan() { createInstance(); } void mainLoop() { while (!glfwWindowShouldClose(window)) { glfwPollEvents(); } } void cleanup() { vkDestroyInstance(instance, nullptr); glfwDestroyWindow(window); glfwTerminate(); } void createInstance() { VkApplicationInfo appInfo{}; appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; appInfo.pApplicationName = "Hello Triangle"; appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); appInfo.pEngineName = "No Engine"; appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); appInfo.apiVersion = VK_API_VERSION_1_0; VkInstanceCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.pApplicationInfo = &appInfo; uint32_t glfwExtensionCount = 0; const char** glfwExtensions; glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); createInfo.enabledExtensionCount = glfwExtensionCount; createInfo.ppEnabledExtensionNames = glfwExtensions; createInfo.enabledLayerCount = 0; if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) { throw std::runtime_error("failed to create instance!"); } } }; int main() { HelloTriangleApplication app; try { app.run(); } catch (const std::exception& e) { std::cerr << e.what() << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS; }
  • 成功:依然是一个黑框口,而且程序关闭时没有报错(退出代码为 0)。这意味着 Instance 创建成功,并且被正确销毁了。

  • 失败:如果抛出了 "failed to create instance!" 异常,通常是因为显卡驱动不支持 Vulkan,或者在某些旧的集成显卡上需要更新驱动。

总结

我们今天完成了 Vulkan 开发中最基础的一步:

  1. 理解了VkApplicationInfoVkInstanceCreateInfo结构体。

  2. 使用vkCreateInstance创建了句柄。

  3. 使用vkDestroyInstance进行了资源清理。

虽然看起来还在原地踏步(还是那个黑窗口),但在后台,你的程序已经成功加载了 Vulkan 驱动并准备好大干一场了。


下一步预告

如果你现在写错了代码(比如传了空指针),程序会直接崩溃,没有任何提示。这在开发中是无法接受的。

下一篇,我们将引入 Vulkan 的守护神 ——校验层 (Validation Layers)。它会像严厉的老师一样,在你犯错时详细地告诉你错在哪里,而不是让你对着崩溃的程序发呆。

详见:Instance - Vulkan Tutorial

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 17:11:00

中文OCR精度新高度|DeepSeek-OCR-WEBUI支持多场景本地化部署

中文OCR精度新高度&#xff5c;DeepSeek-OCR-WEBUI支持多场景本地化部署 1. 背景与技术演进&#xff1a;OCR的挑战与DeepSeek的突破 光学字符识别&#xff08;OCR&#xff09;作为连接物理文档与数字信息的关键技术&#xff0c;长期以来面临复杂场景下的识别难题。传统OCR系统…

作者头像 李华
网站建设 2026/6/15 18:59:53

3分钟掌握鸣潮模组:终极游戏增强完整攻略

3分钟掌握鸣潮模组&#xff1a;终极游戏增强完整攻略 【免费下载链接】wuwa-mod Wuthering Waves pak mods 项目地址: https://gitcode.com/GitHub_Trending/wu/wuwa-mod 还在为《鸣潮》游戏中的各种限制而烦恼吗&#xff1f;想要获得更流畅、更自由的游戏体验&#xff…

作者头像 李华
网站建设 2026/6/15 16:04:28

WuWa-Mod模组完整配置手册:3分钟开启游戏增强之旅

WuWa-Mod模组完整配置手册&#xff1a;3分钟开启游戏增强之旅 【免费下载链接】wuwa-mod Wuthering Waves pak mods 项目地址: https://gitcode.com/GitHub_Trending/wu/wuwa-mod 想要彻底改变游戏体验吗&#xff1f;WuWa-Mod模组为你提供了全面的游戏功能增强方案&…

作者头像 李华
网站建设 2026/6/15 15:22:38

VirtualBrowser数据采集完整指南:5步构建高效自动化工作流

VirtualBrowser数据采集完整指南&#xff1a;5步构建高效自动化工作流 【免费下载链接】VirtualBrowser Free anti fingerprint browser, 指纹浏览器, 隐私浏览器, 免费的web3空投专用指纹浏览器 项目地址: https://gitcode.com/gh_mirrors/vi/VirtualBrowser VirtualBr…

作者头像 李华
网站建设 2026/6/15 18:51:54

终极指南:如何用AI视频总结神器快速掌握B站海量内容

终极指南&#xff1a;如何用AI视频总结神器快速掌握B站海量内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱&#xff0c;支持视频、音乐、番剧、课程下载……持续更新 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTo…

作者头像 李华
网站建设 2026/6/15 14:13:06

图层移动不穿帮!Qwen-Image-Layered精准保留遮挡关系

图层移动不穿帮&#xff01;Qwen-Image-Layered精准保留遮挡关系 1. 引言&#xff1a;图像编辑的“穿帮”难题与分层解法 在传统图像编辑中&#xff0c;移动或缩放前景对象时常出现“穿帮”现象——被遮挡部分未正确恢复、边缘融合生硬、背景信息错乱。这一问题源于像素级操作…

作者头像 李华