Skip to content

Commit c88dca0

Browse files
committed
Refact Specialization
1 parent 6cf3a4f commit c88dca0

File tree

6 files changed

+57
-51
lines changed

6 files changed

+57
-51
lines changed

docs/codes/04/11_specialization/GraphicsPipeline.cppm renamed to docs/codes/04/10_specialization/GraphicsPipeline.cppm

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
1-
module;
2-
3-
#include <memory>
4-
#include <vector>
5-
61
export module GraphicsPipeline;
72

3+
import std;
84
import vulkan_hpp;
95

106
import DataLoader;
11-
import Utility;
7+
import Tools;
128
import Device;
139
import RenderPass;
1410

@@ -31,7 +27,7 @@ export namespace vht {
3127
class GraphicsPipeline {
3228
std::shared_ptr<vht::Device> m_device;
3329
std::shared_ptr<vht::RenderPass> m_render_pass;
34-
vk::raii::DescriptorSetLayout m_descriptor_set_layout{ nullptr };
30+
std::vector<vk::raii::DescriptorSetLayout> m_descriptor_set_layouts;
3531
vk::raii::PipelineLayout m_pipeline_layout{ nullptr };
3632
vk::raii::Pipeline m_pipeline{ nullptr };
3733
public:
@@ -42,7 +38,7 @@ export namespace vht {
4238
}
4339

4440
[[nodiscard]]
45-
const vk::raii::DescriptorSetLayout& descriptor_set_layout() const { return m_descriptor_set_layout; }
41+
const std::vector<vk::raii::DescriptorSetLayout>& descriptor_set_layouts() const { return m_descriptor_set_layouts; }
4642
[[nodiscard]]
4743
const vk::raii::PipelineLayout& pipeline_layout() const { return m_pipeline_layout; }
4844
[[nodiscard]]
@@ -55,28 +51,30 @@ export namespace vht {
5551
}
5652
// 创建描述符集布局
5753
void create_descriptor_set_layout() {
58-
vk::DescriptorSetLayoutBinding ubo_layout_binging;
59-
ubo_layout_binging.binding = 0;
60-
ubo_layout_binging.descriptorType = vk::DescriptorType::eUniformBuffer;
61-
ubo_layout_binging.descriptorCount = 1;
62-
ubo_layout_binging.stageFlags = vk::ShaderStageFlagBits::eVertex;
63-
64-
vk::DescriptorSetLayoutBinding sampler_layout_binding;
65-
sampler_layout_binding.binding = 1;
66-
sampler_layout_binding.descriptorType = vk::DescriptorType::eCombinedImageSampler;
67-
sampler_layout_binding.descriptorCount = 1;
68-
sampler_layout_binding.stageFlags = vk::ShaderStageFlagBits::eFragment;
69-
70-
auto bindings = { ubo_layout_binging, sampler_layout_binding };
71-
vk::DescriptorSetLayoutCreateInfo layoutInfo;
72-
layoutInfo.setBindings( bindings );
73-
74-
m_descriptor_set_layout = m_device->device().createDescriptorSetLayout( layoutInfo );
54+
vk::DescriptorSetLayoutBinding uboLayoutBinding;
55+
uboLayoutBinding.binding = 0;
56+
uboLayoutBinding.descriptorType = vk::DescriptorType::eUniformBuffer;
57+
uboLayoutBinding.descriptorCount = 1;
58+
uboLayoutBinding.stageFlags = vk::ShaderStageFlagBits::eVertex;
59+
60+
vk::DescriptorSetLayoutCreateInfo uboLayoutInfo;
61+
uboLayoutInfo.setBindings( uboLayoutBinding );
62+
m_descriptor_set_layouts.emplace_back( m_device->device().createDescriptorSetLayout( uboLayoutInfo ) );
63+
64+
vk::DescriptorSetLayoutBinding samplerLayoutBinding;
65+
samplerLayoutBinding.binding = 0;
66+
samplerLayoutBinding.descriptorType = vk::DescriptorType::eCombinedImageSampler;
67+
samplerLayoutBinding.descriptorCount = 1;
68+
samplerLayoutBinding.stageFlags = vk::ShaderStageFlagBits::eFragment;
69+
vk::DescriptorSetLayoutCreateInfo samplerLayoutInfo;
70+
71+
samplerLayoutInfo.setBindings( samplerLayoutBinding );
72+
m_descriptor_set_layouts.emplace_back( m_device->device().createDescriptorSetLayout( samplerLayoutInfo ) );
7573
}
7674
// 创建图形管线
7775
void create_graphics_pipeline() {
78-
const auto vertex_shader_code = vht::read_shader("shaders/vert.spv");
79-
const auto fragment_shader_code = vht::read_shader("shaders/frag.spv");
76+
const auto vertex_shader_code = vht::read_shader("shaders/graphics.vert.spv");
77+
const auto fragment_shader_code = vht::read_shader("shaders/graphics.frag.spv");
8078
const auto vertex_shader_module = vht::create_shader_module(m_device->device(), vertex_shader_code);
8179
const auto fragment_shader_module = vht::create_shader_module(m_device->device(), fragment_shader_code);
8280
vk::PipelineShaderStageCreateInfo vertex_shader_create_info;
@@ -93,24 +91,26 @@ export namespace vht {
9391
mapEntry.size = sizeof(float);
9492
// 3. 特化信息
9593
vk::SpecializationInfo specializationInfo;
96-
specializationInfo.setMapEntries(mapEntry);
94+
specializationInfo.setMapEntries(mapEntry); // 如果需要,可以设置多个映射条目
9795
specializationInfo.setData<float>(my_color);
9896
// 此模板设置了 指针 和 数据大小 ,不能放右值
9997

100-
vk::PipelineShaderStageCreateInfo fragment_shader_create_info; // 片段着色器
98+
vk::PipelineShaderStageCreateInfo fragment_shader_create_info;
10199
fragment_shader_create_info.stage = vk::ShaderStageFlagBits::eFragment;
102100
fragment_shader_create_info.module = fragment_shader_module;
103101
fragment_shader_create_info.pName = "main";
104-
fragment_shader_create_info.pSpecializationInfo = &specializationInfo; // 特化信息
102+
103+
// 直接在着色器创建信息中绑定“特化信息”
104+
fragment_shader_create_info.pSpecializationInfo = &specializationInfo;
105105

106106
const auto shader_stages = { vertex_shader_create_info, fragment_shader_create_info };
107107

108108
const auto dynamic_states = { vk::DynamicState::eViewport, vk::DynamicState::eScissor };
109109
vk::PipelineDynamicStateCreateInfo dynamic_state;
110110
dynamic_state.setDynamicStates(dynamic_states);
111111

112-
auto binding_description = vht::Vertex::get_binding_description();
113-
auto attribute_description = vht::Vertex::get_attribute_description();
112+
const auto binding_description = vht::Vertex::get_binding_description();
113+
const auto attribute_description = vht::Vertex::get_attribute_description();
114114
vk::PipelineVertexInputStateCreateInfo vertex_input;
115115
vertex_input.setVertexBindingDescriptions(binding_description);
116116
vertex_input.setVertexAttributeDescriptions(attribute_description);
@@ -152,15 +152,19 @@ export namespace vht {
152152
color_blend.setAttachments( color_blend_attachment );
153153

154154
vk::PipelineLayoutCreateInfo layout_create_info;
155-
layout_create_info.setSetLayouts( *m_descriptor_set_layout );
155+
156+
// 将 raii 类型转换回 vk::DescriptorSetLayout
157+
const auto set_layouts = m_descriptor_set_layouts
158+
| std::views::transform([](const auto& layout) -> vk::DescriptorSetLayout { return layout; })
159+
| std::ranges::to<std::vector>();
160+
161+
layout_create_info.setSetLayouts( set_layouts );
156162
m_pipeline_layout = m_device->device().createPipelineLayout( layout_create_info );
157163

158164
vk::GraphicsPipelineCreateInfo create_info;
159-
create_info.setStages( shader_stages );
160-
161165
create_info.layout = m_pipeline_layout;
162166

163-
167+
create_info.setStages( shader_stages );
164168
create_info.pVertexInputState = &vertex_input;
165169
create_info.pInputAssemblyState = &input_assembly;
166170
create_info.pDynamicState = &dynamic_state;

docs/codes/04/11_specialization/shader.frag renamed to docs/codes/04/10_specialization/graphics.frag.glsl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
#version 450
2+
23
// 提供默认值 0.0
34
layout (constant_id = 0) const float myColor = 0.0;
45

5-
layout(binding = 1) uniform sampler2D texSampler;
6+
layout(set = 1, binding = 0) uniform sampler2D texSampler;
67

78
layout(location = 0) in vec2 fragTexCoord;
89

docs/md/04/11_specialization.md renamed to docs/md/04/10_specialization.md

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,11 @@ comments: true
1010
与推送常量不同,特化常量最后将直接嵌入 SPIR-V 代码中,且管线创建后无法修改,类似于编译时常量。
1111

1212
需要注意,SPIR-V 依然只是一种中间语言,而我们为其嵌入了常量值,因此它可以在生成目标 ISA 时进行优化,如常量折叠、死代码消除等。
13-
14-
综上,它可用于代替高级着色器语言(GLSL/HLSL)中的预处理宏,实现更优雅的着色器代码。
13+
因此,它可用于(部分)代替高级着色器语言(GLSL/HLSL)中的预处理宏,实现更优雅的着色器代码。
1514

1615
## **基础代码**
1716

18-
请下载并阅读下面的基础代码,这依然是“C++模块化”章节的第二部分代码:
17+
请下载并阅读下面的基础代码,这是“C++模块化”章节的第二部分代码:
1918

2019
**[点击下载](../../codes/04/00_cxxmodule/module_code.zip)**
2120

@@ -36,14 +35,16 @@ void main() {
3635
}
3736
```
3837

39-
显然特化常量在各个着色器都可用,此处方便演示,请修改 `shaders/shader.frag` 片段着色器:
38+
显然特化常量在各个着色器都可用,本文以片段着色器为例,请修改 `shaders/graphics.frag.glsl` 文件:
39+
4040

4141
```glsl
4242
#version 450
43-
// 提供默认值 0.0
43+
44+
// 提供默认值 0.0
4445
layout (constant_id = 0) const float myColor = 0.0;
4546
46-
layout(binding = 1) uniform sampler2D texSampler;
47+
layout(set = 1, binding = 0) uniform sampler2D texSampler;
4748
4849
layout(location = 0) in vec2 fragTexCoord;
4950
@@ -92,7 +93,7 @@ mapEntry.offset = 0; // 源数据的起始偏移量
9293
mapEntry.size = sizeof(float);
9394
// 3. 特化信息
9495
vk::SpecializationInfo specializationInfo;
95-
specializationInfo.setMapEntries(mapEntry);
96+
specializationInfo.setMapEntries(mapEntry); // 如果需要,可以设置多个映射条目
9697
specializationInfo.setData<float>(my_color);
9798
// 此模板设置了 指针 和 数据大小 ,不能放右值
9899

@@ -111,7 +112,7 @@ fragment_shader_create_info.pSpecializationInfo = &specializationInfo;
111112

112113
经过基础章节的学习,这些字段你应该能够轻松理解。现在运行程序,你将看到这样的图像:
113114

114-
![../../i](../../images/0411/blue_room.png)
115+
![blue_room](../../images/0411/blue_room.png)
115116

116117

117118
## **最后**
@@ -127,10 +128,10 @@ fragment_shader_create_info.pSpecializationInfo = &specializationInfo;
127128

128129
**[初始代码集](../../codes/04/00_cxxmodule/module_code.zip)**
129130

130-
**[shader.frag](../../codes/04/11_specialization/shader.frag)**
131+
**[shader - frag](../../codes/04/10_specialization/graphics.frag.glsl)**
131132

132-
**[GraphicsPipeline.cppm](../../codes/04/11_specialization/GraphicsPipeline.cppm)**
133+
**[GraphicsPipeline.cppm](../../codes/04/10_specialization/GraphicsPipeline.cppm)**
133134

134-
**[GraphicsPipeline.diff\(差异文件\)](../../codes/04/11_specialization/GraphicsPipeline.diff)**
135+
**[GraphicsPipeline.diff\(差异文件\)](../../codes/04/10_specialization/GraphicsPipeline.diff)**
135136

136137
---

docs/todo.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ comments: true
88
```
99
- 进阶功能:
1010
- 杂项:
11-
- 特化常量: md/04/11_specialization.md # 待重构
1211
- 查询池: md/04/10_querypool.md # 待重构
1312
- TODO: todo.md # pNext 与 sType + 同步2.0语法 + 动态渲染 + 辅助命令缓冲 - 管线缓存
1413
- 多管线渲染:

mkdocs.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,10 @@ nav:
8181
- 计算着色器与SSBO: md/03/80_compute.md
8282
- 进阶功能:
8383
- C++模块化: md/04/00_cxxmodule.md
84+
- 杂项:
85+
- 特化常量: md/04/10_specialization.md
8486
- 待重构:
85-
- 杂项:
86-
- 特化常量: md/04/11_specialization.md
87+
- 杂项_:
8788
- 查询池: md/04/10_querypool.md
8889
- TODO: todo.md # pNext 与 sType + 同步2.0语法 + 动态渲染 + 辅助命令缓冲 - 管线缓存
8990
- 多管线渲染:

0 commit comments

Comments
 (0)