FCT
载入中...
搜索中...
未找到
VK_PassGroup.cpp
浏览该文件的文档.
1#include "../ThirdParty.h"
3#include "./VK_PassGroup.h"
6#include "./VK_Pass.h"
8
9namespace FCT
10{
11 namespace RHI
12 {
14 {
15 m_ctx = ctx;
16 }
17
19 {
20 if (m_renderPass)
21 {
22 m_ctx->device().destroyRenderPass(m_renderPass);
23 }
24 for (auto& it : m_framebuffers)
25 {
26 if (it.second)
27 m_ctx->device().destroyFramebuffer(it.second);
28 }
29 }
30
32 {
34 for (auto& pass : m_passes)
35 {
36 pass->create(this);
37 }
38 m_createInfo.attachmentCount = m_attachments.size();
39 m_createInfo.pAttachments = m_attachments.data();
40
41 std::vector<vk::SubpassDependency> dependencies;
42 /*
43 bool hasDepthStencil = !m_depthAttachments.empty();
44
45 vk::SubpassDependency dependency{};
46 dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
47 dependency.dstSubpass = 0;
48
49 if (hasDepthStencil) {
50 dependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput |
51 vk::PipelineStageFlagBits::eEarlyFragmentTests;
52 } else {
53 dependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
54 }
55
56 dependency.srcAccessMask = vk::AccessFlags();
57
58 if (hasDepthStencil) {
59 dependency.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput |
60 vk::PipelineStageFlagBits::eEarlyFragmentTests;
61 dependency.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite |
62 vk::AccessFlagBits::eDepthStencilAttachmentWrite;
63 } else {
64 dependency.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
65 dependency.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite;
66 }
67
68 dependencies.push_back(dependency);
69
70 vk::SubpassDependency outDependency{};
71 outDependency.srcSubpass = 0;
72 outDependency.dstSubpass = VK_SUBPASS_EXTERNAL;
73
74 if (hasDepthStencil) {
75 outDependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput |
76 vk::PipelineStageFlagBits::eLateFragmentTests;
77 outDependency.srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite |
78 vk::AccessFlagBits::eDepthStencilAttachmentWrite;
79 } else {
80 outDependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
81 outDependency.srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite;
82 }
83
84 outDependency.dstStageMask = vk::PipelineStageFlagBits::eBottomOfPipe;
85 outDependency.dstAccessMask = vk::AccessFlagBits::eMemoryRead;
86 dependencies.push_back(outDependency);
87
88 if (m_subpasses.size() > 1) {
89 for (size_t i = 0; i < m_subpasses.size() - 1; i++) {
90 vk::SubpassDependency subpassDependency{};
91 subpassDependency.srcSubpass = i;
92 subpassDependency.dstSubpass = i + 1;
93
94 subpassDependency.srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
95 subpassDependency.srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite;
96
97 if (hasDepthStencil) {
98 subpassDependency.srcStageMask |= vk::PipelineStageFlagBits::eLateFragmentTests;
99 subpassDependency.srcAccessMask |= vk::AccessFlagBits::eDepthStencilAttachmentWrite;
100 }
101
102 subpassDependency.dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;
103 subpassDependency.dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite;
104
105 if (hasDepthStencil) {
106 subpassDependency.dstStageMask |= vk::PipelineStageFlagBits::eEarlyFragmentTests;
107 subpassDependency.dstAccessMask |= vk::AccessFlagBits::eDepthStencilAttachmentWrite;
108 }
109
110 dependencies.push_back(subpassDependency);
111 }
112 }*/
113 for (auto desc : m_passDescs)
114 {
115 for (auto pre : desc.predecessors)
116 {
117 vk::SubpassDependency dependency{};
118 dependency.srcSubpass = toPassForDependencies(pre.pass);
119 dependency.srcStageMask = ToVkPipelineStageFlags(pre.neighborStage);
120 dependency.srcAccessMask = ToVkAccessFlags(pre.neighborAccess);
121 dependency.dstSubpass = getPassIndex(desc.pass);
122 dependency.dstStageMask = ToVkPipelineStageFlags(pre.currentStage);
123 dependency.dstAccessMask = ToVkAccessFlags(pre.currentAccess);
124 dependencies.push_back(dependency);
125 }
126 }
127 m_createInfo.setDependencies(dependencies);
128
130 m_createInfo.pSubpasses = m_subpasses.data();
131 m_createInfo.subpassCount = m_subpasses.size();
132
133 try {
134 m_renderPass = m_ctx->device().createRenderPass(m_createInfo);
135 } catch (const std::exception& e) {
136 ferr << "Failed to create render pass: " << e.what() << std::endl;
137 throw;
138 }
139
140 m_beginInfo.renderPass = m_renderPass;
141 m_framebufferInfo.renderPass = m_renderPass;
142 }
144 {
145 return m_passIndices[pass];
146 }
147
149 {
151 if (m_framebuffers[cmdBuf])
152 {
153 m_ctx->device().destroyFramebuffer(m_framebuffers[cmdBuf]);
154 m_framebuffers[cmdBuf] = nullptr;
155 }
156
157 m_framebufferInfo.attachmentCount = m_framebufferViews.size();
158 m_framebufferInfo.pAttachments = m_framebufferViews.data();
159
160 if (m_targetAttachments.empty() && m_depthAttachments.empty()) {
161 fout << "No attachments for framebuffer!" << std::endl;
162 return;
163 }
164
165 uint32_t width, height;
166 if (!m_targetAttachments.empty()) {
167 width = m_targetAttachments.rbegin()->second.image->width();
168 height = m_targetAttachments.rbegin()->second.image->height();
169 } else {
170 width = m_depthAttachments.rbegin()->second.image->width();
171 height = m_depthAttachments.rbegin()->second.image->height();
172 }
173 m_framebufferInfo.width = width;
174 m_framebufferInfo.height = height;
175 m_framebufferInfo.layers = 1;
176 m_framebufferInfo.renderPass = m_renderPass;
177
178 try {
179 m_framebuffers[cmdBuf] = m_ctx->device().createFramebuffer(m_framebufferInfo);
180 } catch (const std::exception& e) {
181 ferr << "Failed to create framebuffer: " << e.what() << std::endl;
182 throw;
183 }
184
185 m_beginInfo.framebuffer = m_framebuffers[cmdBuf];
186 m_beginInfo.renderArea.offset.setX(0).setY(0);
187 m_beginInfo.renderArea.extent.width = width;
188 m_beginInfo.renderArea.extent.height = height;
189
190 m_clearValues = std::vector<vk::ClearValue>(m_attachments.size());
191 for (size_t i = 0; i < m_clearValues.size(); i++) {
192 if (m_depthAttachments.find(i) != m_depthAttachments.end()) {
193 m_clearValues[i].setDepthStencil(vk::ClearDepthStencilValue(1.0f, 0));
194 } else {
195 m_clearValues[i].setColor(vk::ClearColorValue(std::array<float, 4>{0.0f, 0.0f, 0.0f, 1.0f}));
196 }
197 }
198
199 m_beginInfo.setClearValues(m_clearValues);
200
201 auto vkCmdBuf = static_cast<VK_CommandBuffer*>(cmdBuf);
202 vkCmdBuf->commandBuffer().beginRenderPass(m_beginInfo, vk::SubpassContents::eInline);
204 m_passes[m_currentPassIndex]->executeClear(cmdBuf);
205 }
206
208 {
209 auto vkCmdBuf = static_cast<VK_CommandBuffer*>(cmdBuf);
210 if (m_targetAttachments.empty() && m_depthAttachments.empty()) {
211 return;
212 }
213
214 vkCmdBuf->commandBuffer().endRenderPass();
215 if (m_currentPassIndex < m_passes.size() - 1)
216 {
217 fout << "[warnning] submit pass num < pass count.\n";
218 }
219 }
220
222 {
223 cmdBuf->nextPass();
225 m_passes[m_currentPassIndex]->executeClear(cmdBuf);
226 }
227
229 {
230 for (auto& srcPass : m_passes)
231 {
232 auto pass = (VK_Pass*&)(srcPass);
233 m_passIndices[pass] = m_subpasses.size();
234 m_subpasses.push_back(pass->getDescription());
235 }
236 }
237/*
238 void VK_PassGroup::collectAttachments()
239 {
240 for (auto& pass : m_passes)
241 {
242 for (auto& targetPair : pass->renderTargets())
243 {
244 auto& image = targetPair.second;
245 vk::AttachmentDescription desc;
246 desc.format = ToVkFormat(image->format());
247 desc.samples = ToVkSampleCount(image->samples());
248 desc.loadOp = vk::AttachmentLoadOp::eClear;
249 desc.storeOp = vk::AttachmentStoreOp::eStore;
250 desc.initialLayout = vk::ImageLayout::eUndefined;
251 //todo:优化initialLayout
252 if (image->getType() == RenderTargetType::WindowTarget && !m_nextPassGroup.size())
253 {
254 desc.finalLayout = vk::ImageLayout::ePresentSrcKHR;
255 } else
256 {
257 desc.finalLayout = vk::ImageLayout::eGeneral;
258 //Todo: 根据nextPassGroup来优化finalLayout,或者由外部手动指定finalLayout
259 }
260 desc.stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
261 desc.stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
262
263 m_targetAttachments[m_attachments.size()] = AttachmentSlot(
264 image,
265 ImageUsage::RenderTarget,
266 targetPair.first);
267 auto vkPass = static_cast<VK_Pass*>(pass);
268 vkPass->targetAttachmentIndices()[targetPair.first] = m_attachments.size();
269 m_attachments.push_back(desc);
270 }
271
272 auto vkPass = static_cast<VK_Pass*>(pass);
273 FCT::Image* depthStencil = vkPass->depthStencil();
274 if (depthStencil)
275 {
276 vk::AttachmentDescription desc;
277 desc.format = ToVkFormat(depthStencil->format());
278 desc.samples = ToVkSampleCount(depthStencil->samples());
279
280 desc.loadOp = vk::AttachmentLoadOp::eClear;
281 desc.storeOp = vk::AttachmentStoreOp::eStore;
282
283 if (desc.format == vk::Format::eD24UnormS8Uint ||
284 desc.format == vk::Format::eD32SfloatS8Uint ||
285 desc.format == vk::Format::eD16UnormS8Uint)
286 {
287 desc.stencilLoadOp = vk::AttachmentLoadOp::eClear;
288 desc.stencilStoreOp = vk::AttachmentStoreOp::eStore;
289 }
290 else
291 {
292 desc.stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
293 desc.stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
294 }
295
296 desc.initialLayout = vk::ImageLayout::eUndefined;
297 desc.finalLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
298
299 m_depthAttachments[m_attachments.size()] = AttachmentSlot(
300 depthStencil,
301 ImageUsage::DepthStencil,
302 0);
303
304 vkPass->setDepthStencilAttachmentIndex(m_attachments.size());
305
306 m_attachments.push_back(desc);
307 }
308 }
309 }
310*/
312 {
313 std::map<FCT::Image*, uint32_t> imageToAttachmentIndex;
314
315 for (auto& pass : m_passes)
316 {
317 auto vkPass = static_cast<VK_Pass*>(pass);
318
319 for (auto& targetPair : pass->renderTargets())
320 {
321 auto& image = targetPair.second;
322 uint32_t attachmentIndex;
323
324 auto it = imageToAttachmentIndex.find(image);
325 if (it != imageToAttachmentIndex.end()) {
326 attachmentIndex = it->second;
327 } else {
328 vk::AttachmentDescription desc;
329 desc.format = ToVkFormat(image->format());
330 desc.samples = ToVkSampleCount(image->samples());
331
332 desc.storeOp = vk::AttachmentStoreOp::eStore;
333 if (image->getType() == RenderTargetType::WindowTarget) {
334 desc.loadOp = vk::AttachmentLoadOp::eLoad;
335 desc.initialLayout = vk::ImageLayout::eColorAttachmentOptimal; // 不能是Undefined
336 } else {
337 desc.loadOp = vk::AttachmentLoadOp::eLoad;
338 desc.initialLayout = vk::ImageLayout::eColorAttachmentOptimal;
339 }
340
341 if (image->getType() == RenderTargetType::WindowTarget && !m_nextPassGroup.size()) {
342 desc.finalLayout = vk::ImageLayout::ePresentSrcKHR;
343 } else {
344 desc.finalLayout = vk::ImageLayout::eGeneral;
345 }
346
347 desc.stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
348 desc.stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
349
350 attachmentIndex = m_attachments.size();
351 m_attachments.push_back(desc);
352
353 imageToAttachmentIndex[image] = attachmentIndex;
354
355 m_targetAttachments[attachmentIndex] = AttachmentSlot(
356 image,
358 targetPair.first);
359 }
360
361 vkPass->targetAttachmentIndices()[targetPair.first] = attachmentIndex;
362 }
363
364 FCT::Image* depthStencil = vkPass->depthStencil();
365 if (depthStencil)
366 {
367 uint32_t attachmentIndex;
368
369 auto it = imageToAttachmentIndex.find(depthStencil);
370 if (it != imageToAttachmentIndex.end()) {
371 attachmentIndex = it->second;
372 } else {
373 vk::AttachmentDescription desc;
374 desc.format = ToVkFormat(depthStencil->format());
375 desc.samples = ToVkSampleCount(depthStencil->samples());
376
377 desc.loadOp = vk::AttachmentLoadOp::eLoad;
378 desc.storeOp = vk::AttachmentStoreOp::eStore;
379
380 if (desc.format == vk::Format::eD24UnormS8Uint ||
381 desc.format == vk::Format::eD32SfloatS8Uint ||
382 desc.format == vk::Format::eD16UnormS8Uint ||
383 desc.format == vk::Format::eD32Sfloat
384 )
385 {
386 desc.stencilLoadOp = vk::AttachmentLoadOp::eLoad;
387 desc.stencilStoreOp = vk::AttachmentStoreOp::eStore;
388 }
389 else
390 {
391 desc.stencilLoadOp = vk::AttachmentLoadOp::eDontCare;
392 desc.stencilStoreOp = vk::AttachmentStoreOp::eDontCare;
393 }
394
395 desc.initialLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
396 desc.finalLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
397
398 attachmentIndex = m_attachments.size();
399 m_attachments.push_back(desc);
400
401 imageToAttachmentIndex[depthStencil] = attachmentIndex;
402
403 m_depthAttachments[attachmentIndex] = AttachmentSlot(
406 0);
407 }
408
409 vkPass->setDepthStencilAttachmentIndex(attachmentIndex);
410 }
411 }
412 }
413 void VK_PassGroup::collectImageViews() // 注意,顺序要保持和collectAttachments一样
414 {
415 m_framebufferViews.clear();
416 m_framebufferViews.resize(m_attachments.size());
417
418 for (const auto& [attachmentIndex, slot] : m_targetAttachments) {
419 auto& image = slot.image;
420 m_framebufferViews[attachmentIndex] =
421 static_cast<VK_RenderTargetView*>(image->currentTargetView())->view();
422 }
423
424 for (const auto& [attachmentIndex, slot] : m_depthAttachments) {
425 auto& image = slot.image;
426 auto dsv = image->currentDepthStencilView();
427 if (dsv) {
428 auto vkDsv = static_cast<VK_DepthStencilView*>(dsv);
429 m_framebufferViews[attachmentIndex] = vkDsv->getImageView();
430 } else {
431 ferr << "Depth stencil image has no depth stencil view!" << std::endl;
432 }
433 }
434 }
435
437 {
438 if (pass == Pass::external || pass == Pass::begin || pass == Pass::present || !m_passIndices.contains(pass))
439 {
440 return VK_SUBPASS_EXTERNAL;
441 }
442 return m_passIndices[pass];
443 }
444
445 /*
446 void VK_PassGroup::collectImageViews() // 注意,顺序要保持和collectAttachments一样
447 {
448 m_framebufferViews.clear();
449
450 // 收集渲染目标视图
451 for (auto& pass : m_passes)
452 {
453 for (auto& targetPair : pass->renderTargets())
454 {
455 auto& image = targetPair.second;
456 m_framebufferViews.push_back(
457 static_cast<VK_RenderTargetView*>(image->currentTargetView())->view());
458 }
459
460 auto vkPass = static_cast<VK_Pass*>(pass);
461 FCT::Image* depthStencil = vkPass->depthStencil();
462 if (depthStencil)
463 {
464 auto dsv = depthStencil->currentDepthStencilView();
465 if (dsv)
466 {
467 auto vkDsv = static_cast<VK_DepthStencilView*>(dsv);
468 m_framebufferViews.push_back(vkDsv->getImageView());
469 }
470 else
471 {
472 ferr << "Depth stencil image has no depth stencil view!" << std::endl;
473 }
474 }
475 }
476 }
477 */
478 }
479}
virtual void nextPass()=0
std::vector< PassDesc > m_passDescs
std::vector< PassGroup * > m_nextPassGroup
std::vector< Pass * > m_passes
static constexpr Pass * present
定义 Pass.h:25
static constexpr Pass * external
定义 Pass.h:24
static constexpr Pass * begin
定义 Pass.h:26
std::unordered_map< RHI::CommandBuffer *, vk::Framebuffer > m_framebuffers
std::map< Pass *, uint32_t > m_passIndices
uint32_t getPassIndex(Pass *pass)
vk::FramebufferCreateInfo m_framebufferInfo
void nextPass(CommandBuffer *cmdBuf) override
开始下一个pass的 提交
std::vector< vk::SubpassDescription > m_subpasses
std::vector< vk::AttachmentDescription > m_attachments
vk::RenderPassBeginInfo m_beginInfo
void beginSubmit(CommandBuffer *cmdBuf) override
vk::RenderPassCreateInfo m_createInfo
std::map< uint32_t, AttachmentSlot > m_depthAttachments
void endSubmit(CommandBuffer *cmdBuf) override
uint32_t toPassForDependencies(Pass *pass)
std::map< uint32_t, AttachmentSlot > m_targetAttachments
std::vector< vk::ImageView > m_framebufferViews
std::vector< vk::ClearValue > m_clearValues
std::ostream & ferr
std::ostream & fout
vk::SampleCountFlagBits ToVkSampleCount(Samples samples)
vk::Format ToVkFormat(Format format)
vk::PipelineStageFlags ToVkPipelineStageFlags(FCT::PipelineStages pipelineStages)