Skip to content

Commit aa86848

Browse files
committed
Change Subpass dependency content
1 parent 2c676ca commit aa86848

18 files changed

+128
-190
lines changed

docs/index.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@ comments: true
2626
- [CMake](https://cmake.org/) 构建系统
2727
- [vcpkg](https://vcpkg.io/) 依赖管理
2828

29-
`CMake` 用于项目构建,实现跨平台的项目配置,要求读者了解 CMake 的基础使用。
30-
31-
`vcpkg` 用于管理第三方库,主要用于安装 `glfw3``glm` 等依赖,这非常简单。
32-
3329
## **其他说明**
3430

3531
Vulkan SDK 本身由 C 编写,因此具有更好的跨语言兼容性,可通过 C 接口供其他语言调用。

docs/md/00/00_intro.md

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ comments: true
7070

7171
3. 然后需要找一些机器人帮我们画画,也就是物理设备 `VkPhysicalDevice` ,常代指 GPU 。
7272

73-
4. 机器人有很多机械臂,有的可以画画,有的可以扫地,我们需要选择合适的机械臂去完成任务。一个机械臂对应一个队列 `VkQueue` ,一组支持特定功能的机械臂称为队列族 `VkQueueFamily`比如绘画队列族
73+
4. 机器人有很多机械臂,有的可以画画,有的可以扫地,我们需要选择合适的机械臂去完成任务。一个机械臂对应一个队列 `VkQueue` ,一组支持特定功能的机械臂称为队列族 `VkQueueFamily`比如计算队列族
7474

7575
5. 机器人\(GPU\)的型号不同,但我们希望有相同的操作方式,于是设计了统一的接口,这就是逻辑设备 `VkDevice` ,用于抽象物理设备。
7676

@@ -80,29 +80,25 @@ comments: true
8080

8181
8. 我们看画的速度和机器人画画的速度不一样,为了保证效率,可以用一个盒子作为缓冲。机器人往盒子里放画,扫描仪从盒子里拿画。这个盒子就是交换链 `VkSwapchainKHR`
8282

83-
9. 特别的是,这些画画的纸可以重复使用,所以盒子里的纸的总数是固定的。这些纸就是图像 `VkImage`交换链中的图像总数固定
83+
9. 这些纸代指图像 `VkImage`,还需要一个标记描述纸张的材质等信息,即 `VkImageView`描述图像的基本信息
8484

85-
10. 不同的纸可能有不同的材质和大小,所以我们需要给每个纸写一个标签。这个标签就是图像视图 `VkImageView`描述图像的基本信息
85+
10. 现在机器人终于可以画画了,我们要为他准备一个画桌,用于放置画纸等工具。这个画桌就是帧缓冲 `VkFrameBuffer`一帧代指一幅图像
8686

87-
11. 现在机器人终于可以画画了,我们要为他准备一个画桌,用于放置画纸等工具。这个画桌就是帧缓冲 `VkFrameBuffer` ,一帧代指一幅图像
87+
11. 我们还要为机器人设计一个房子,这个房子代指渲染通道 `VkRenderPass`,而纸张对应其中的附件 `Attachments`
8888

89-
12. 我们还要为机器人设计一个房子,这个房子代指渲染通道 `VkRenderPass`,而纸张对应其中的附件 `Attachments`
89+
12. 虽然这些附件放置\(绑定\)在画桌\(帧缓冲\)上,但我们需要提前写明房子中有哪些附件,即附件描述 `AttachmentDesctiption`
9090

91-
13. 虽然这些附件放置\(绑定\)在画桌\(帧缓冲\)上,但我们需要为房子贴上告示牌,写明房子内有哪些附件,即附件描述 `AttachmentDesctiption`
91+
13. 机器人很笨,只能看着流程图画画,所以你需要在房子中放置一些流程图。这个流程图就代指图形管线 `VkGraphicsPipeline`
9292

93-
14. 机器人很笨,只能看着流程图画画,所以你需要在房子中放置一些流程图。这个流程图就代指图形管线 `VkGraphicsPipeline`
93+
14. 图形管线的某几个部分是可编程的,这里就用到了着色器模块 `Shader Module`
9494

95-
15. 一个大房子分成多个小房间(可以只有一个),可以用不同的房间干不同的事,这些小房间就是子通道 `VkSubpass` ,一个子通道绑定一个图形管线
95+
15. 这些机器人很呆,需要你写信告诉他该画画了、如何画画。这些信代指命令缓冲 `VkCommandBuffer`
9696

97-
16. 我们有一份流程图的模版,只需要修改它的部分内容就可以变成新的流程图。其中某几个部分是可编程的,这里就用到了着色器模块 `Shader Module`
97+
16. 信可以重用,我们使用一个命令池 `VkCommandPool` 管理这些资源
9898

99-
17. 这些机器人很呆,需要你写信告诉他该画画了,在哪个房子的哪些房间根据哪些流程图画画。这些信代指命令缓冲 `VkCommandBuffer`
99+
17. 我们需要保证机器人先画画,画完才能放入扫描仪,因此使用信号量 `Semaphore` 处理 GPU 自身的同步。还要保证机器人先完成一张画,我们再给它新的信,所以使用围栏 `Fence` 处理 CPU 和 GPU 之间的同步
100100

101-
18. 特殊的是信可以重用,我们使用一个命令池 `VkCommandPool` 管理这些资源。
102-
103-
19. 事情一多,机器人做起来就乱了。要保证它先画画,画完才能把画拿出去,所以我们用信号量 `Semaphore` 处理 GPU 自身的同步。还要保证机器人先完成一张画,我们再寄出新的信,所以我们使用围栏 `Fence` 处理 CPU 和 GPU 之间的同步。
104-
105-
绘制第一个三角形大致就是这些内容,你目前**不需要记住**,在后面的学习中随时可以回顾此内容。
101+
绘制第一个三角形大致就是这些步骤,你目前**不需要记住**,在后面的学习中随时可以回顾此内容。
106102

107103
### 注意
108104

docs/md/00/01_env.md

Lines changed: 35 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -12,81 +12,61 @@ comments: true
1212
> 作为跨平台的教程,我们不限制编译器的选择,但请保证它支持您需要的 C++ 标准。
1313
1414
## **安装 Vulkan SDK**
15+
1516
Vulkan SDK 是开发Vulkan应用程序的核心组件,包含:
1617

1718
- 头文件
1819
- 函数加载器
1920
- 标准验证层
20-
- 着色器编译支持
21-
- ······
21+
- 开发辅助库
2222

2323
可以从 [LunarG官网](https://vulkan.lunarg.com/) 下载SDK,无需注册账户。
2424

25+
### Windows
2526

26-
### Windows 安装
27-
1.**[官网](https://vulkan.lunarg.com/)** 下载 Vulkan SDK 并运行安装程序,**允许它设置环境变量**
28-
2. 验证安装:
29-
- 进入 SDK 安装目录的 Bin 子目录
30-
- 运行 vkcube.exe 演示程序
31-
- 应看到旋转的立方体窗口
27+
[官网](https://vulkan.lunarg.com/sdk/home#windows) 下载 Vulkan SDK 并运行安装程序,**允许它设置环境变量**(如果可选)。
3228

33-
![cube](../../images/0001/cube_demo.png)
29+
#### 验证安装:
3430

35-
### Linux
31+
进入 SDK 安装目录的 Bin 子目录,运行 vkcube.exe 演示程序:
3632

37-
#### 图形界面安装
38-
参考Windows安装方法。
33+
![cube](../../images/0001/cube_demo.png)
3934

40-
#### 命令行安装:
41-
Ubuntu/Debian系
42-
```shell
43-
sudo apt install vulkan-tools libvulkan-dev vulkan-validationlayers-dev spirv-tools
44-
```
35+
### Linux
4536

46-
Fedora/RHEL系
47-
```shell
48-
sudo dnf install vulkan-tools vulkan-loader-devel mesa-vulkan-devel vulkan-validation-layers-devel
49-
```
37+
推荐 [LunarG官网](https://vulkan.lunarg.com/sdk/home#linux) 下载。
5038

51-
Arch Linux
52-
```shell
53-
sudo pacman -S vulkan-devel
54-
```
39+
使用命令行安装请参考 [此文档](https://vulkan.lunarg.com/doc/sdk/latest/linux/getting_started.html)
5540

5641
#### 验证安装:
42+
5743
```shell
5844
vkcube
5945
```
6046

61-
确保您看到以下窗口弹出
47+
确保您看到以下窗口弹出
6248

6349
![cube](../../images/0001/cube_demo_nowindow.png)
6450

6551

66-
### MacOS 安装
67-
68-
要求:
69-
70-
- MacOS 10.11或更高版本
71-
- 支持Metal API的硬件
52+
### MacOS
7253

73-
步骤:
54+
要求:MacOS 10.11或更高版本,支持Metal API的硬件。
7455

75-
1. [LunarG官网](https://vulkan.lunarg.com/) 下载SDK
56+
[LunarG官网](https://vulkan.lunarg.com/sdk/home#mac) 下载 SDK 并解压到选定目录。
7657

77-
2. 解压到选定目录
78-
79-
3. 运行 `Applications` 目录下的 `vkcube` 演示程序
58+
#### 验证安装:
8059

81-
您应该看到以下内容
60+
运行 `Applications` 目录下的 `vkcube` 演示程序,您应该看到以下内容
8261

8362
![cube](../../images/0001/cube_demo_mac.png)
8463

8564
## **依赖库安装**
8665

87-
我们使用 vcpkg 作为跨平台包管理器,安装方式请参考 [官方文档](https://learn.microsoft.com/zh-cn/vcpkg/get_started/overview)
66+
我们使用 vcpkg 进行依赖管理,它是由微软管理,是 C++ 目前最通用的包管理工具,安装方式请参考 [官方文档](https://learn.microsoft.com/zh-cn/vcpkg/get_started/overview)
8867

8968
### GLFW
69+
9070
Vulkan 本身是一个平台无关的 API,不包含用于创建窗口以显示渲染结果的工具。
9171
我们将使用 [GLFW](http://www.glfw.org/) 库来创建窗口,它支持 Windows、Linux 和 MacOS,且和 Vulkan 有很好的集成。
9272

@@ -95,14 +75,21 @@ Vulkan 本身是一个平台无关的 API,不包含用于创建窗口以显示
9575
vcpkg install glfw3
9676
```
9777

78+
> Vulkan SDK 还内置了 SDL2 窗口库,它更加强大,但远比 GLFW 复杂。
79+
> GAMES104 的 Piccolo 引擎也使用 GLFW ,它完全可以满足本教程的需求。
80+
9881
### GLM
99-
与 DirectX 12 不同,Vulkan 不包含用于线性代数运算的库。我们使用 [GLM](https://github.com/g-truc/glm) 线性代数库,它专为图形 API 设计,常用于 OpenGL 与 Vulkan 。
82+
83+
与 DirectX 12 不同,Vulkan 并不内置线性代数工具。我们使用 [GLM](https://github.com/g-truc/glm) 线性代数库,它专为图形 API 设计,常用于 OpenGL 与 Vulkan 。
10084

10185
安装命令:
86+
10287
```shell
10388
vcpkg install glm
10489
```
10590

91+
> SDK 中其实附带了 glm ,但这里依然推荐你使用 vcpkg 安装。
92+
10693
## **项目初始化**
10794

10895
### 目录结构
@@ -119,11 +106,10 @@ vcpkg install glm
119106

120107
### CMake配置
121108

122-
1. 设置工具链为vcpkg。
123-
2. 设定项目C++标准。
124-
3. 查找Vulkan,glm,glfw3三个库。
125-
4. 添加主程序。
126-
5. 链接库。
109+
1. 设置工具链为 vcpkg 。
110+
2. 设定项目 C++ 标准。
111+
3. 查找 Vulkan,glm,glfw3 三个库。
112+
4. 添加主程序并链接库。
127113

128114
**参考代码:**
129115

@@ -208,7 +194,7 @@ int main() {
208194
}
209195
```
210196

211-
你无需理解上述C++代码的含义,这只是测试库是否成功导入。
197+
你无需理解上述 C++ 代码的含义,这只是测试库是否成功导入。
212198

213199
### 构建运行
214200

@@ -236,16 +222,16 @@ build/HelloVulkan
236222

237223
### 关于CMake预设
238224

239-
注意:**CMake预设不是必须的**,我们没有复杂的配置需求,你完全可以通过上面两行简单的CMake指令构建项目!
225+
**CMake预设不是必须的**,我们没有复杂的配置需求,你完全可以通过上面两行简单的CMake指令构建项目!
240226

241-
如果你喜欢使用 `CMakePresets.json` 它可以很好地和 CLion、VSCode、Visual Studio 配合),可以参考 **[这个](../../codes/00/01_env/CMakePresets.json)** 预设模板。
227+
如果你喜欢使用 `CMakePresets.json` \(它可以很好地和 CLion、VSCode、Visual Studio 集成\),可以参考 **[这个](../../codes/00/01_env/CMakePresets.json)** 预设模板。
242228

243229
此预设模板使用 Ninja 作为生成器,提供了 MSVC/GNU/Clang 工具链的预设配置。
244230

245231
## **代码编辑器**
246232

247233
建议使用一个足够智能的编辑器。
248-
当你不确定某些函数的参数和它的含义时,可以右键函数并跳转到它的定义并查看实现。Visual Studio / VSCode / CLion都能提供此功能
234+
当你不确定某些函数的参数和它的含义时,可以右键函数跳转到它的定义并查看实现。Visual Studio / VSCode / CLion 都提供此功能
249235

250236
---
251237

docs/md/00/02_diff.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,4 @@ VkSemaphore ctype_semaphore = **raii_semaphore;
181181
| 扩展名 | 保持宏定义不变 | 保持宏定义不变 |
182182
| 结构体初始化 | 需手动设置大部分内容 | 构造函数提供成员初始化 |
183183
184-
> 提示:本教程主要使用 C++ RAII 封装,既保持现代 C++ 风格,又能简化资源管理。
185-
186-
---
187-
188-
下面让我们开始绘制第一个三角形!!
189-
190184
---

docs/md/01/00_base.md

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ comments: true
55
# **基础代码**
66

77
## **总体结构**
8-
在“开发环境”章节中,我们创建了一个 Vulkan 项目,其中包含所有正确的配置,并使用示例代码进行了测试。
8+
在“开发环境”章节中,我们创建了一个 Vulkan 项目,包含了所有正确的配置,并使用示例代码进行了测试。
99

1010
在本章中,我们将从以下代码开始,请修改 `main.cpp`
1111

@@ -60,6 +60,7 @@ int main() {
6060
`vk::SystemError` 可以捕获大部分 Vulkan 异常,你可以使用 `.code()` 成员函数判断异常类型。
6161

6262
## **集成 GLFW**
63+
6364
离屏渲染无需窗口也能完美运行,但我们希望实时地显示一些东西。
6465

6566
### 1. 添加GLFW支持
@@ -131,7 +132,8 @@ void mainLoop() {
131132
它循环并检查事件,例如按下 `X` 按钮,直到窗口被用户关闭。 `glfwPollEvents` 函数将处理本次循环期间发生的所有窗口事件。
132133

133134
### 5. 清理资源
134-
一旦窗口关闭,我们需要销毁窗口并终止 GLFW 本身从而清理资源。
135+
136+
在窗口关闭后,我们需要销毁窗口并终止 GLFW 本身从而清理资源。
135137

136138
```cpp
137139
void cleanup() {
@@ -142,17 +144,12 @@ void cleanup() {
142144

143145
## **尝试运行**
144146

145-
现在运行程序,您应该看到一个标题为 Vulkan 的窗口出现,直到应用程序在窗口关闭时终止
147+
现在运行程序,您应该看到一个标题为 Vulkan 的窗口出现,可以点击关闭按键结束程序
146148

147149
![empty_window](../../images/0001/glfw.png)
148150

149151
---
150152

151-
需要说明的是,基础部分的代码重点在于功能演示,因此可能忽略**可选**`const``static` 等 C++ 标识符细节。
152-
但进阶部分会提供尽量优雅的基础代码框架。
153-
154-
---
155-
156153
**[C++代码](../../codes/01/00_base/main.cpp)**
157154

158155
**[CMake代码](../../codes/01/00_base/CMakeLists.txt)**

docs/md/01/01_instance.md

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,7 @@ vk::InstanceCreateInfo createInfo(
9696
`flags` 参数是标志位,用于控制特殊行为,默认认初始化为空,大多时候无需修改。
9797
还有其他参数,但都提供了默认初始化,无需手动设置。
9898

99-
`&applicationInfo` 传入指针,需要注意生命周期:
100-
101-
1. `CreateInfo`仅用于提供配置信息。
102-
2. `CreateInfo`在创建对应资源后就无用了。
103-
3. 只需要保证指针在创建对象时有效。
99+
`&applicationInfo` 传入指针,需要注意生命周期:`CreateInfo`仅用于提供配置信息,它在创建对应资源后就无用了,因此只需保证指针在创建对象时有效。
104100

105101
### 3. 创建实例
106102

@@ -160,6 +156,8 @@ Vulkan-Hpp 需要调用底层C接口,所以这些配置信息采用相同的
160156
> 实际上,每个成员变量还有自身的 `setter` ,他们和直接赋值是等效的。
161157
> 为了方便区分,如果是单参数,本教程直接赋值而不用 `setter` 函数。
162158
159+
此外,这些 setter 函数返回对象自身的引用,因此可以链式调用。
160+
163161
### 3. 测试与运行
164162

165163
现在尝试构建与运行项目,非MacOS不应该出现错误。
@@ -169,15 +167,14 @@ Vulkan-Hpp 需要调用底层C接口,所以这些配置信息采用相同的
169167
> 特征:err.code() 为 `vk::Result::eErrorIncompatibleDriver`
170168
171169
在使用 MoltenVK SDK 的 MacOS 上,可能抛出异常,因为 MacOS 在运行 Vulkan 时必须启用转换层扩展。
170+
我们需要修改 `CreateInfo` 配置:
172171

173-
**解决方案:**
172+
- 添加 `vk::KHRPortabilityEnumerationExtensionName` 扩展
173+
- 添加 `vk::InstanceCreateFlagBits::eEnumeratePortabilityKHR` 标志位
174174

175-
1. 修改 `CreateInfo`
176-
2. 添加 `vk::KHRPortabilityEnumerationExtensionName` 扩展
177-
3. 添加 `vk::InstanceCreateFlagBits::eEnumeratePortabilityKHR` 标志位
178175

176+
通常代码可能如下所示:
179177

180-
通常代码可能如下所示
181178
```cpp
182179
std::vector<const char*> requiredExtensions( glfwExtensions, glfwExtensions + glfwExtensionCount );
183180
requiredExtensions.emplace_back(vk::KHRPortabilityEnumerationExtensionName);

docs/md/01/03_physicaldevice.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ void selectPhysicalDevice() {
4545
}
4646
```
4747

48-
> 你可能见过 `vk::raii::PhysicalDevices` 类型,它末尾多了个 `s`
49-
> 他实际上继承了 `std::vector<vk::raii::PhysicalDevice>` ,二者功能基本一致。
48+
> 你可能见过 `vk::raii::PhysicalDevices` 类型,末尾多了个 `s`
49+
> 它实际上继承了 `std::vector<vk::raii::PhysicalDevice>` ,二者功能基本一致。
5050
5151
### 3. 设备适用性检查
5252

docs/md/01/04_device.md

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -66,17 +66,15 @@ queueCreateInfo.setQueuePriorities( queuePriority );
6666
6767
### 3. 指定设备特性
6868

69-
目前我们不需要任何特殊的东西,可以直接使用默认值。 当我们开始使用 Vulkan 做更有趣的事情时,会回来修改到这个结构。
70-
7169
我们之前提到过,物理设备还有很多可选特性,它们的支持性取决于具体的 GPU 硬件。
7270
如果需要使用这些特性,要在逻辑设备创建时显式启用它们,但我们现在还没有需要的特性。
7371

72+
目前我们不需要任何特殊的东西,可以直接使用默认值。 当我们开始使用 Vulkan 做更有趣的事情时,会回来修改到这个结构。
73+
7474
```cpp
7575
vk::PhysicalDeviceFeatures deviceFeatures;
7676
```
7777

78-
后续章节提到的“需要启用 GPU 特性”指得就是这里。
79-
8078
### 4. 创建信息
8179

8280
有了前面的两个结构,我们就可以填写 `vk::DeviceCreateInfo` 结构了。
@@ -87,22 +85,12 @@ createInfo.setQueueCreateInfos( queueCreateInfo );
8785
createInfo.pEnabledFeatures = &deviceFeatures;
8886
```
8987

90-
其余信息与 `vk::InstanceCreateInfo` 结构相似,并要求您指定扩展。不同之处在于这次这些是设备特定的。
91-
92-
> 注意,虽然设备特定的“层”已废弃,但仍然需要指定设备特定的扩展与设备特性。
88+
其余信息与 `vk::InstanceCreateInfo` 结构相似,并要求您指定扩展,但这次是设备特定的。
89+
我们暂时没有扩展需要添加,因此无需填写。
9390

94-
### 5. 验证层
95-
96-
设备特定的层很早就被废弃,你无需也不应该使用它们,以下代码将被 Vulkan 忽略。
97-
98-
```cpp
99-
if constexpr (ENABLE_VALIDATION_LAYER) {
100-
// 无效代码
101-
createInfo.setPEnabledLayerNames( REQUIRED_LAYERS );
102-
}
103-
```
91+
> 实例除了“扩展”外还有“层”的概念。设备特定的“层”已弃用很久了,请不要使用它。
10492
105-
### 6. 创建逻辑设备
93+
### 5. 创建逻辑设备
10694

10795
目前我们不需要任何设备特定的扩展,可以实例化逻辑设备了:
10896

docs/md/01/10_surface.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ m_graphicsQueue = m_device.getQueue( graphics.value(), 0 );
160160
m_presentQueue = m_device.getQueue( present.value(), 0 );
161161
```
162162

163-
如果队列族相同,这两个句柄很可能具有相同的值,但这依然可以正常运行
163+
如果队列族相同,这两个句柄很可能具有相同的值,但依然可以正常运行
164164

165165
## **测试**
166166

0 commit comments

Comments
 (0)