88
99#include " StateTracking.hpp"
1010#include " DebugUtils.hpp"
11- #include " etna/GpuWorkCount.hpp"
11+ #include < etna/GpuWorkCount.hpp>
1212
1313
1414namespace etna
@@ -194,13 +194,23 @@ 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 =
210+ static_cast <std::uint32_t >(etna::get_context ().getMainWorkCount ().multiBufferingCount ());
211+ std::uint32_t semsCount = std::max (imageCount, numFramesInFlight);
212+
213+ newSwapchain.imageAvailable .resize (semsCount);
204214 for (std::size_t i = 0 ; i < newSwapchain.imageAvailable .size (); ++i)
205215 {
206216 newSwapchain.imageAvailable [i] =
@@ -209,7 +219,7 @@ Window::SwapchainData Window::createSwapchain(const DesiredProperties& props) co
209219 newSwapchain.imageAvailable [i].get (), fmt::format (" Swapchain image {} available" , i).c_str ());
210220 }
211221
212- newSwapchain.imageReadyForPresent .resize (imageCount );
222+ newSwapchain.imageReadyForPresent .resize (semsCount );
213223 for (std::size_t i = 0 ; i < newSwapchain.imageReadyForPresent .size (); ++i)
214224 {
215225 newSwapchain.imageReadyForPresent [i] =
0 commit comments