1+ // Copyright (C) 2023-2023 - DevSH Graphics Programming Sp. z O.O.
2+ // This file is part of the "Nabla Engine".
3+ // For conditions of distribution and use, see copyright notice in nabla.h
4+ #ifndef _NBL_VIDEO_C_DEFAULT_SWAPCHAIN_FRAMEBUFFERS_HPP_INCLUDED_
5+ #define _NBL_VIDEO_C_DEFAULT_SWAPCHAIN_FRAMEBUFFERS_HPP_INCLUDED_
6+
7+
8+ // Build on top of the previous one
9+ #include " nabla.h"
10+
11+
12+ namespace nbl ::video
13+ {
14+
15+ // Just a class to create a Default single Subpass Renderpass and hold framebuffers derived from swapchain images.
16+ // WARNING: It assumes the format won't change between swapchain recreates!
17+ class CDefaultSwapchainFramebuffers : public ISimpleManagedSurface ::ISwapchainResources
18+ {
19+ public:
20+ inline CDefaultSwapchainFramebuffers (ILogicalDevice* device, const asset::E_FORMAT format, const IGPURenderpass::SCreationParams::SSubpassDependency* dependencies)
21+ {
22+ // If we create the framebuffers by default, we also need to default the renderpass (except dependencies)
23+ const IGPURenderpass::SCreationParams::SColorAttachmentDescription colorAttachments[] = {
24+ {{
25+ .format = format,
26+ .samples = IGPUImage::ESCF_1_BIT,
27+ .mayAlias = false ,
28+ .loadOp = IGPURenderpass::LOAD_OP::CLEAR,
29+ .storeOp = IGPURenderpass::STORE_OP::STORE,
30+ .initialLayout = IGPUImage::LAYOUT::UNDEFINED, // because we clear we don't care about contents
31+ .finalLayout = IGPUImage::LAYOUT::PRESENT_SRC // transition to presentation right away so we can skip a barrier
32+ }},
33+ IGPURenderpass::SCreationParams::ColorAttachmentsEnd
34+ };
35+ IGPURenderpass::SCreationParams::SSubpassDescription subpasses[] = {
36+ {},
37+ IGPURenderpass::SCreationParams::SubpassesEnd
38+ };
39+ subpasses[0 ].colorAttachments [0 ] = {.render ={.attachmentIndex =0 ,.layout =IGPUImage::LAYOUT::ATTACHMENT_OPTIMAL}};
40+
41+ IGPURenderpass::SCreationParams params = {};
42+ params.colorAttachments = colorAttachments;
43+ params.subpasses = subpasses;
44+ params.dependencies = dependencies;
45+ m_renderpass = device->createRenderpass (params);
46+ }
47+
48+ inline IGPURenderpass* getRenderpass () {return m_renderpass.get ();}
49+
50+ inline IGPUFramebuffer* getFrambuffer (const uint8_t imageIx)
51+ {
52+ if (imageIx<m_framebuffers.size ())
53+ return m_framebuffers[imageIx].get ();
54+ return nullptr ;
55+ }
56+
57+ protected:
58+ virtual inline void invalidate_impl ()
59+ {
60+ std::fill (m_framebuffers.begin (),m_framebuffers.end (),nullptr );
61+ }
62+
63+ // For creating extra per-image or swapchain resources you might need
64+ virtual inline bool onCreateSwapchain_impl (const uint8_t qFam)
65+ {
66+ auto device = const_cast <ILogicalDevice*>(m_renderpass->getOriginDevice ());
67+
68+ const auto swapchain = getSwapchain ();
69+ const auto count = swapchain->getImageCount ();
70+ const auto & sharedParams = swapchain->getCreationParameters ().sharedParams ;
71+ for (uint8_t i=0u ; i<count; i++)
72+ {
73+ auto imageView = device->createImageView ({
74+ .flags = IGPUImageView::ECF_NONE,
75+ .subUsages = IGPUImage::EUF_RENDER_ATTACHMENT_BIT,
76+ .image = core::smart_refctd_ptr<IGPUImage>(getImage (i)),
77+ .viewType = IGPUImageView::ET_2D,
78+ .format = getImage (i)->getCreationParameters ().format
79+ });
80+ m_framebuffers[i] = device->createFramebuffer ({{
81+ .renderpass = core::smart_refctd_ptr (m_renderpass),
82+ .colorAttachments = &imageView.get (),
83+ .width = sharedParams.width ,
84+ .height = sharedParams.height
85+ }});
86+ if (!m_framebuffers[i])
87+ return false ;
88+ }
89+ return true ;
90+ }
91+
92+ core::smart_refctd_ptr<IGPURenderpass> m_renderpass;
93+ // Per-swapchain
94+ std::array<core::smart_refctd_ptr<IGPUFramebuffer>,ISwapchain::MaxImages> m_framebuffers;
95+ };
96+
97+ }
98+ #endif
0 commit comments