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