Skip to content

renderFinishedSemaphores incorrectly allocated per swapchain image instead of per frame in flight #310

@Rageoholic

Description

@Rageoholic

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:

// 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 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions