KhronosGroup / KhronosGroup/Vulkan-Tutorial

`renderFinishedSemaphores` incorrectly allocated per swapchain image instead of per frame in flight

Open Beginner friendly
#310 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
418
Forks
126
Avg merge
11d 6h
Merged PRs (30d)
31

Description

**Page:** https://docs.vulkan.org/tutorial/latest/03_Drawing_a_triangle/03_Drawing/03_Frames_in_flight.html

In `createSyncObjects`, the three sync objects are allocated with inconsistent bounds:

```cpp
// Per swapchain image:
for (size_t i = 0; i < swapChainImages.size(); i++)
renderFinishedSemaphores.emplace_back(...);

// Per frame in flight:
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
presentCompleteSemaphores.emplace_back(...);
inFlightFences.emplace_back(...);
}
```

This contradicts the tutorial's own stated design principle — that resources accessed during rendering must be duplicated per concurrent frame, not per swapchain image — and introduces three concrete problems:

**1. Index mismatch.** `presentCompleteSemaphores` is indexed by `current_frame`; `renderFinishedSemaphores` is indexed by the `image_index` returned from `vkAcquireNextImageKHR`. These are independent values that happen to alias in simple cases but have no guaranteed relationship. The submit/present code mixes two different index schemes without acknowledgment.

**2. Swapchain recreation requires semaphore teardown.** Semaphores keyed by swapchain image count must be destroyed and recreated whenever the swapchain is recreated (resize, etc.), because the image count can change. Semaphores keyed by `MAX_FRAMES_IN_FLIGHT` survive swapchain recreation untouched. The tutorial never addresses this, leaving readers with code that will silently break on resize unless they independently discover and fix the lifetime issue. The [swapchain recreation page](https://docs.vulkan.org/tutorial/latest/03_Drawing_a_triangle/04_Swap_chain_recreation.html) also does not document that the semaphore count could theoretically change on recreation — in practice drivers likely return the same image count, which is probably why this went unnoticed.

**3. Over-allocation.** The Vulkan spec requires `swapChainImages.size() >= MAX_FRAMES_IN_FLIGHT`, so this always creates at least as many `renderFinishedSemaphores` as needed, and usually more.

### Fix

Allocate `renderFinishedSemaphores` in the same loop as the other per-frame resources (bounded by `MAX_FRAMES_IN_FLIGHT`) and index it by `current_frame` at submit/present time, the same as `presentCompleteSemaphores` and `inFlightFences`.

---

*This issue was generated with the assistance of Claude.*

Contributor guide

Open the contributing guide

Research direction

Start with createSyncObjects on the Frames in flight tutorial page, then inspect the submit and present code that indexes the synchronization objects. Allocate renderFinishedSemaphores with the per-frame resources and use current_frame consistently; verify the swapchain recreation page no longer needs to account for their lifetime.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
computer-graphics, documentation
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.