Skip to content

Commit 0c882e7

Browse files
authored
Window: fix sems count (#74)
We must have a unique sems pair for each inflight frame
1 parent 8625ac6 commit 0c882e7

File tree

5 files changed

+26
-3
lines changed

5 files changed

+26
-3
lines changed

etna/include/etna/GpuSharedResource.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ class GpuSharedResource
8181
f(impl[i].get());
8282
}
8383

84+
const GpuWorkCount* getWorkCount() const { return workCount; }
85+
8486
~GpuSharedResource() noexcept
8587
{
8688
for (std::size_t i = 0; i < workCount->multiBufferingCount(); ++i)

etna/include/etna/PerFrameCmdMgr.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ class PerFrameCmdMgr
5252
vk::Semaphore write_attachments_after,
5353
vk::Semaphore&& use_result_after);
5454

55+
std::size_t getCmdBufferCount() const;
56+
5557
private:
5658
vk::Device device;
5759
vk::Queue submitQueue;

etna/include/etna/Window.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ class Window
8686
* Should be disabled whenever tone mapping is being performed manually in shaders.
8787
*/
8888
bool autoGamma = true;
89+
90+
/**
91+
* Should be equal to the number of command buffers used to draw images in the swapchain.
92+
*/
93+
uint32_t numFramesInFlight = 1;
8994
};
9095
/**
9196
* Recreates the swapchain with the provided desired resolution

etna/source/PerFrameCmdMgr.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,9 @@ vk::Semaphore PerFrameCmdMgr::submit(
9191
return use_result_after;
9292
}
9393

94+
std::size_t PerFrameCmdMgr::getCmdBufferCount() const
95+
{
96+
return buffers->getWorkCount()->multiBufferingCount();
97+
}
98+
9499
} // namespace etna

etna/source/Window.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
#include "StateTracking.hpp"
1010
#include "DebugUtils.hpp"
11-
#include "etna/GpuWorkCount.hpp"
11+
#include <etna/GpuWorkCount.hpp>
1212

1313

1414
namespace etna
@@ -194,13 +194,22 @@ Window::SwapchainData Window::createSwapchain(const DesiredProperties& props) co
194194
// wayland and there is nothing we can do about it.
195195
const auto extent = chose_swap_extent(surfaceCaps, props.resolution);
196196

197+
// Why + 1 ? see https://vulkan-tutorial.com/Drawing_a_triangle/Presentation/Swap_chain
197198
std::uint32_t imageCount = surfaceCaps.minImageCount + 1;
198199
if (surfaceCaps.maxImageCount > 0)
199200
imageCount = std::min(imageCount, surfaceCaps.maxImageCount);
200201

201202
SwapchainData newSwapchain;
202203

203-
newSwapchain.imageAvailable.resize(imageCount);
204+
// We must have unique sems (aquire and preset) for each inflight frame,
205+
// because we don't want to complicate synchronization with fences.
206+
// There is no sync between CPU and GPU (because prev line),
207+
// so if you want to change MAX_FRAMES_INFLIGHT to a higher value,
208+
// think twice about it!
209+
const auto numFramesInFlight = static_cast<std::uint32_t>(props.numFramesInFlight);
210+
std::uint32_t semsCount = std::max(imageCount, numFramesInFlight);
211+
212+
newSwapchain.imageAvailable.resize(semsCount);
204213
for (std::size_t i = 0; i < newSwapchain.imageAvailable.size(); ++i)
205214
{
206215
newSwapchain.imageAvailable[i] =
@@ -209,7 +218,7 @@ Window::SwapchainData Window::createSwapchain(const DesiredProperties& props) co
209218
newSwapchain.imageAvailable[i].get(), fmt::format("Swapchain image {} available", i).c_str());
210219
}
211220

212-
newSwapchain.imageReadyForPresent.resize(imageCount);
221+
newSwapchain.imageReadyForPresent.resize(semsCount);
213222
for (std::size_t i = 0; i < newSwapchain.imageReadyForPresent.size(); ++i)
214223
{
215224
newSwapchain.imageReadyForPresent[i] =

0 commit comments

Comments
 (0)