Skip to content

Commit 18af976

Browse files
Improve format choice and move CDefaultSwapchainFramebuffers.h to nbl::video
1 parent f53d23f commit 18af976

File tree

6 files changed

+120
-4
lines changed

6 files changed

+120
-4
lines changed

include/nbl/video/declarations.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "nbl/video/utilities/SPhysicalDeviceFilter.h"
3838
#include "nbl/video/utilities/CSimpleResizeSurface.h"
3939
#include "nbl/video/utilities/CSmoothResizeSurface.h"
40+
#include "nbl/video/utilities/CDefaultSwapchainFramebuffers.h"
4041

4142
//VT
4243
//#include "nbl/video/CGPUMeshPackerV2.h"
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
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

include/nbl/video/utilities/CSimpleResizeSurface.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class CSimpleResizeSurface final : public ISimpleManagedSurface
5454
// need to see if the swapchain is invalidated (e.g. because we're starting from 0-area old Swapchain) and try to recreate the swapchain
5555
inline uint8_t acquireNextImage()
5656
{
57-
if (m_swapchainResources && m_swapchainResources->getStatus()!=ISwapchainResources::STATUS::USABLE && !recreateSwapchain())
57+
if (!m_swapchainResources || m_swapchainResources->getStatus()!=ISwapchainResources::STATUS::USABLE && !recreateSwapchain())
5858
return ISwapchain::MaxImages;
5959
return ISimpleManagedSurface::acquireNextImage();
6060
}
@@ -112,7 +112,13 @@ class CSimpleResizeSurface final : public ISimpleManagedSurface
112112
.sharedParams = m_sharedParams
113113
// we're not going to support concurrent sharing in this simple class
114114
};
115-
if (params.deduceFormat(device->getPhysicalDevice()))
115+
const bool success = params.deduceFormat(
116+
device->getPhysicalDevice(),
117+
m_swapchainResources->getPreferredFormats(),
118+
m_swapchainResources->getPreferredEOTFs(),
119+
m_swapchainResources->getPreferredColorPrimaries()
120+
);
121+
if (success)
116122
newSwapchain = CVulkanSwapchain::create(core::smart_refctd_ptr<const ILogicalDevice>(device),std::move(params));
117123
}
118124
}

include/nbl/video/utilities/CSmoothResizeSurface.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,13 @@ class NBL_API2 ISmoothResizeSurface : public ISimpleManagedSurface
252252
.sharedParams = m_sharedParams
253253
// we're not going to support concurrent sharing in this simple class
254254
};
255-
if (params.deduceFormat(device->getPhysicalDevice()))
255+
const bool success = params.deduceFormat(
256+
device->getPhysicalDevice(),
257+
swapchainResources->getPreferredFormats(),
258+
swapchainResources->getPreferredEOTFs(),
259+
swapchainResources->getPreferredColorPrimaries()
260+
);
261+
if (success)
256262
newSwapchain = CVulkanSwapchain::create(core::smart_refctd_ptr<const ILogicalDevice>(device),std::move(params));
257263
}
258264
}

include/nbl/video/utilities/ISimpleManagedSurface.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ class NBL_API2 ISimpleManagedSurface : public core::IReferenceCounted
6767
friend class ISimpleManagedSurface;
6868

6969
public:
70+
//
71+
virtual inline std::span<const asset::E_FORMAT> getPreferredFormats() const {return ISwapchain::SCreationParams::DefaultPreferredFormats;}
72+
virtual inline std::span<const asset::ELECTRO_OPTICAL_TRANSFER_FUNCTION> getPreferredEOTFs() const {return ISwapchain::SCreationParams::DefaultEOTFs;}
73+
virtual inline std::span<const asset::E_COLOR_PRIMARIES> getPreferredColorPrimaries() const {return ISwapchain::SCreationParams::DefaultColorPrimaries;}
74+
7075
// If `init` not called yet this might return nullptr, or the old stale swapchain that should be retired
7176
inline ISwapchain* getSwapchain() const {return swapchain.get();}
7277

0 commit comments

Comments
 (0)