FCT
载入中...
搜索中...
未找到
VK_TraditionalPipeline.cpp
浏览该文件的文档.
1//
2// Created by Administrator on 2025/3/24.
3//
8#include "./VK_VertexShader.h"
9#include "./VK_PixelShader.h"
11namespace FCT
12{
13 namespace RHI
14 {
19
25
27 {
28 if (!resource)
29 return;
30 switch (resource->getType())
31 {
33 m_vertexShader = static_cast<FCT::VertexShader*>(resource);
34 m_vertexShader->addRef();
35 /*
36 m_vertexShader = static_cast<VK_VertexShader*>(static_cast<FCT::VertexShader*>(resource)->vertexShader());
37 m_vertexShader->addRef();
38 */
39 break;
41 m_pixelShader = static_cast<FCT::PixelShader*>(resource);
42 m_pixelShader->addRef();
43 /*
44 m_pixelShader = static_cast<VK_PixelShader*>(static_cast<FCT::PixelShader*>(resource)->pixelShader());
45 m_pixelShader->addRef();*/
46 break;
47 default:
49 break;
50 }
51 }
52
62 {
63 FCT::VertexShader* vs = nullptr;
64 if (!m_vertexShader)
65 {
66 m_vertexShader = m_ctx->createResource<FCT::VertexShader>();
67 for (auto pair : m_vertexLayouts)
68 {
69 m_vertexShader->addLayout(pair.first, pair.second);
70 }
71 m_vertexShader->resourceLayout(m_resourceLayout);
72 m_vertexShader->pixelLayout(m_pixelLayout);
73 m_vertexShader->create();
74 }
75 if (!m_pixelShader)
76 {
77 m_pixelShader = m_ctx->createResource<FCT::PixelShader>();
78 m_pixelShader->pixelLayout(m_pixelLayout);
79 m_pixelShader->resourceLayout(m_resourceLayout);
80 m_pixelShader->create();
81 }
82 if (!m_inputLayout)
83 {
84 m_inputLayout = static_cast<VK_InputLayout*>(m_vertexShader->createBindedInputLayout());
85 m_inputLayout->create();
86 }
87 }
89 {
90 std::map<uint32_t, std::set<uint32_t>> usedBindings;
91 std::map<uint32_t, std::map<std::string, uint32_t>> resourceBindings; // 记录每个资源名称对应的binding
92 std::map<uint32_t, std::vector<vk::DescriptorSetLayoutBinding>> setBindings;
93
95 {
96 auto shaderBinary = m_vertexShader->binaryCode();
97
98 auto constBufferLocations = shaderBinary.constBufferLocations();
99 auto constBufferLayouts = shaderBinary.constBufferLayout();
100
101 for (const auto& [name, location] : constBufferLocations)
102 {
103 uint32_t set = location.first;
104 uint32_t binding = location.second;
105
106 if (resourceBindings[set].find(name) != resourceBindings[set].end()) {
107 continue;
108 }
109
110 resourceBindings[set][name] = binding;
111 usedBindings[set].insert(binding);
112
113 auto layoutIt = constBufferLayouts.find(name);
114 if (layoutIt == constBufferLayouts.end()) {
115 continue;
116 }
117
118 const ConstLayout& layout = layoutIt->second;
119 vk::ShaderStageFlags stageFlags = ConvertToVkShaderStageFlags(layout.getShaderStages());
120
121 vk::DescriptorSetLayoutBinding layoutBinding(
122 binding,
123 vk::DescriptorType::eUniformBuffer,
124 1,
125 stageFlags,
126 nullptr
127 );
128
129 setBindings[set].push_back(layoutBinding);
130 }
131
132 auto textureLocations = shaderBinary.textureLocations();
133 auto textureLayouts = shaderBinary.textureLayout();
134
135 for (const auto& [name, location] : textureLocations)
136 {
137 uint32_t set = location.first;
138 uint32_t binding = location.second;
139
140 if (resourceBindings[set].find(name) != resourceBindings[set].end()) {
141 continue;
142 }
143
144 if (usedBindings[set].find(binding) != usedBindings[set].end()) {
145 binding = 0;
146 while (usedBindings[set].find(binding) != usedBindings[set].end()) {
147 binding++;
148 }
149 }
150
151 resourceBindings[set][name] = binding;
152 usedBindings[set].insert(binding);
153
154 auto layoutIt = textureLayouts.find(name);
155 if (layoutIt == textureLayouts.end()) {
156 continue;
157 }
158
159 const TextureElement& texture = layoutIt->second;
160 vk::ShaderStageFlags stageFlags = ConvertToVkShaderStageFlags(texture.getShaderStages());
161
162 vk::DescriptorSetLayoutBinding layoutBinding(
163 binding,
164 vk::DescriptorType::eSampledImage,
165 1,
166 stageFlags,
167 nullptr
168 );
169
170 setBindings[set].push_back(layoutBinding);
171 }
172
173 auto samplerLocations = shaderBinary.samplerLocations();
174 auto samplerLayouts = shaderBinary.samplerLayout();
175
176 for (const auto& [name, location] : samplerLocations)
177 {
178 uint32_t set = location.first;
179 uint32_t binding = location.second;
180
181 if (resourceBindings[set].find(name) != resourceBindings[set].end()) {
182 continue;
183 }
184
185 if (usedBindings[set].find(binding) != usedBindings[set].end()) {
186 binding = 0;
187 while (usedBindings[set].find(binding) != usedBindings[set].end()) {
188 binding++;
189 }
190 }
191
192 resourceBindings[set][name] = binding;
193 usedBindings[set].insert(binding);
194
195 auto layoutIt = samplerLayouts.find(name);
196 if (layoutIt == samplerLayouts.end()) {
197 continue;
198 }
199
200 const SamplerElement& sampler = layoutIt->second;
201 vk::ShaderStageFlags stageFlags = ConvertToVkShaderStageFlags(sampler.getShaderStages());
202
203 vk::DescriptorSetLayoutBinding layoutBinding(
204 binding,
205 vk::DescriptorType::eSampler,
206 1,
207 stageFlags,
208 nullptr
209 );
210
211 setBindings[set].push_back(layoutBinding);
212 }
213 }
214
215 if (m_pixelShader)
216 {
217 auto shaderBinary = m_pixelShader->binaryCode();
218
219 auto constBufferLocations = shaderBinary.constBufferLocations();
220 auto constBufferLayouts = shaderBinary.constBufferLayout();
221
222 for (const auto& [name, location] : constBufferLocations)
223 {
224 uint32_t set = location.first;
225 uint32_t binding = location.second;
226
227 if (resourceBindings[set].find(name) != resourceBindings[set].end()) {
228 continue;
229 }
230
231 if (usedBindings[set].find(binding) != usedBindings[set].end()) {
232 binding = 0;
233 while (usedBindings[set].find(binding) != usedBindings[set].end()) {
234 binding++;
235 }
236 }
237
238 resourceBindings[set][name] = binding;
239 usedBindings[set].insert(binding);
240
241 auto layoutIt = constBufferLayouts.find(name);
242 if (layoutIt == constBufferLayouts.end()) {
243 continue;
244 }
245
246 const ConstLayout& layout = layoutIt->second;
247 vk::ShaderStageFlags stageFlags = ConvertToVkShaderStageFlags(layout.getShaderStages());
248
249 vk::DescriptorSetLayoutBinding layoutBinding(
250 binding,
251 vk::DescriptorType::eUniformBuffer,
252 1,
253 stageFlags,
254 nullptr
255 );
256
257 setBindings[set].push_back(layoutBinding);
258 }
259
260 auto textureLocations = shaderBinary.textureLocations();
261 auto textureLayouts = shaderBinary.textureLayout();
262
263 for (const auto& [name, location] : textureLocations)
264 {
265 uint32_t set = location.first;
266 uint32_t binding = location.second;
267
268 if (resourceBindings[set].find(name) != resourceBindings[set].end()) {
269 continue;
270 }
271
272 if (usedBindings[set].find(binding) != usedBindings[set].end()) {
273 binding = 0;
274 while (usedBindings[set].find(binding) != usedBindings[set].end()) {
275 binding++;
276 }
277 }
278
279 resourceBindings[set][name] = binding;
280 usedBindings[set].insert(binding);
281
282 auto layoutIt = textureLayouts.find(name);
283 if (layoutIt == textureLayouts.end()) {
284 continue;
285 }
286
287 const TextureElement& texture = layoutIt->second;
288 vk::ShaderStageFlags stageFlags = ConvertToVkShaderStageFlags(texture.getShaderStages());
289
290 vk::DescriptorSetLayoutBinding layoutBinding(
291 binding,
292 vk::DescriptorType::eSampledImage,
293 1,
294 stageFlags,
295 nullptr
296 );
297
298 setBindings[set].push_back(layoutBinding);
299 }
300
301 auto samplerLocations = shaderBinary.samplerLocations();
302 auto samplerLayouts = shaderBinary.samplerLayout();
303
304 for (const auto& [name, location] : samplerLocations)
305 {
306 uint32_t set = location.first;
307 uint32_t binding = location.second;
308
309 if (resourceBindings[set].find(name) != resourceBindings[set].end()) {
310 continue;
311 }
312
313 if (usedBindings[set].find(binding) != usedBindings[set].end()) {
314 binding = 0;
315 while (usedBindings[set].find(binding) != usedBindings[set].end()) {
316 binding++;
317 }
318 }
319
320 resourceBindings[set][name] = binding;
321 usedBindings[set].insert(binding);
322
323 auto layoutIt = samplerLayouts.find(name);
324 if (layoutIt == samplerLayouts.end()) {
325 continue;
326 }
327
328 const SamplerElement& sampler = layoutIt->second;
329 vk::ShaderStageFlags stageFlags = ConvertToVkShaderStageFlags(sampler.getShaderStages());
330
331 vk::DescriptorSetLayoutBinding layoutBinding(
332 binding,
333 vk::DescriptorType::eSampler,
334 1,
335 stageFlags,
336 nullptr
337 );
338
339 setBindings[set].push_back(layoutBinding);
340 }
341 }
342
344 for (const auto& [set, bindings] : setBindings) {
345 vk::DescriptorSetLayoutCreateInfo layoutInfo(
346 vk::DescriptorSetLayoutCreateFlags(),
347 static_cast<uint32_t>(bindings.size()),
348 bindings.data()
349 );
350
351 try {
352 m_descriptorSetLayouts[set] = m_ctx->getDevice().createDescriptorSetLayout(layoutInfo);
353 } catch (const vk::SystemError& e) {
354 throw std::runtime_error("Failed to create descriptor set layout: " + std::string(e.what()));
355 }
356 }
357
359 if (!m_descriptorSetLayouts.empty()) {
360 uint32_t maxSet = 0;
361 for (const auto& [set, layout] : m_descriptorSetLayouts) {
362 maxSet = std::max(maxSet, set);
363 }
364
365 vk::DescriptorSetLayoutCreateInfo emptyLayoutInfo(
366 vk::DescriptorSetLayoutCreateFlags(),
367 0,
368 nullptr
369 );
370 vk::DescriptorSetLayout emptyLayout;
371 try {
372 emptyLayout = m_ctx->getDevice().createDescriptorSetLayout(emptyLayoutInfo);
373 } catch (const vk::SystemError& e) {
374 throw std::runtime_error("Failed to create empty descriptor set layout: " + std::string(e.what()));
375 }
376
377 m_descriptorSetLayoutsArr.resize(maxSet + 1, emptyLayout);
378
379 for (const auto& [set, layout] : m_descriptorSetLayouts) {
380 m_descriptorSetLayoutsArr[set] = layout;
381 }
382
383 m_emptyLayout = emptyLayout;
384 }
385
386 vk::PipelineLayoutCreateInfo pipelineLayoutInfo(
387 vk::PipelineLayoutCreateFlags(),
388 static_cast<uint32_t>(m_descriptorSetLayoutsArr.size()),
389 m_descriptorSetLayoutsArr.empty() ? nullptr : m_descriptorSetLayoutsArr.data(),
390 0,
391 nullptr
392 );
393
394 try {
395 m_pipelineLayout = m_ctx->getDevice().createPipelineLayout(pipelineLayoutInfo);
396 } catch (const vk::SystemError& e) {
397 throw std::runtime_error("Failed to create pipeline layout: " + std::string(e.what()));
398 }
399 }
400 }
401}
constexpr ShaderStages getShaderStages() const noexcept
virtual PipelineResourceType getType() const =0
PixelLayout m_pixelLayout
ResourceLayout m_resourceLayout
std::map< uint32_t, VertexLayout > m_vertexLayouts
vk::PipelineShaderStageCreateInfo getStageInfo() const
std::vector< vk::PipelineShaderStageCreateInfo > m_shaderStages
std::map< uint32_t, vk::DescriptorSetLayout > m_descriptorSetLayouts
std::vector< vk::DescriptorSetLayout > m_descriptorSetLayoutsArr
virtual void addResources(IPipelineResource *resource)
void addResources(IPipelineResource *resource) override
vk::PipelineShaderStageCreateInfo getStageInfo()
constexpr ShaderStages getShaderStages() const noexcept
constexpr ShaderStages getShaderStages() const noexcept
@ Traditional
vk::ShaderStageFlags ConvertToVkShaderStageFlags(ShaderStages stages)