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