quick and dirty frames in flight

This commit is contained in:
Warwick 2025-01-16 17:18:30 +00:00
parent df7f62ff8b
commit a6c3d2b0f2
2 changed files with 45 additions and 37 deletions

View file

@ -30,16 +30,16 @@ file(GLOB_RECURSE HEADER_FILES
${CMAKE_SOURCE_DIR}/src/*.h) ${CMAKE_SOURCE_DIR}/src/*.h)
add_executable(${PROJECT_NAME} ${HEADER_FILES} ${SOURCE_FILES}) add_executable(${PROJECT_NAME} ${HEADER_FILES} ${SOURCE_FILES})
# Error on memory address issues in debug mode ## Error on memory address issues in debug mode
if(CMAKE_BUILD_TYPE MATCHES "Debug") #if(CMAKE_BUILD_TYPE MATCHES "Debug")
set( # set(
CMAKE_C_FLAGS # CMAKE_C_FLAGS
"${CMAKE_C_FLAGS} -Werror -fsanitize=undefined -fsanitize=address" # "${CMAKE_C_FLAGS} -Werror -fsanitize=undefined -fsanitize=address"
) # )
target_link_options(${PROJECT_NAME} # target_link_options(${PROJECT_NAME}
BEFORE PUBLIC -fsanitize=undefined PUBLIC -fsanitize=address # BEFORE PUBLIC -fsanitize=undefined PUBLIC -fsanitize=address
) # )
endif() #endif()
# Link Libraries # Link Libraries
target_link_libraries(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME}

View file

@ -18,6 +18,8 @@ const bool enableValidationLayers = false;
const bool enableValidationLayers = true; const bool enableValidationLayers = true;
#endif #endif
#define MAX_FRAMES_IN_FLIGHT 2
static VKAPI_ATTR VkBool32 VKAPI_CALL static VKAPI_ATTR VkBool32 VKAPI_CALL
debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType, VkDebugUtilsMessageTypeFlagsEXT messageType,
@ -61,11 +63,11 @@ typedef struct Application {
VkFramebuffer *swapChainFramebuffers; VkFramebuffer *swapChainFramebuffers;
uint32_t swapChainFramebufferCount; uint32_t swapChainFramebufferCount;
VkCommandPool commandPool; VkCommandPool commandPool;
VkCommandBuffer commandBuffer; VkCommandBuffer commandBuffers[MAX_FRAMES_IN_FLIGHT];
VkSemaphore imageAvailableSemaphore; VkSemaphore imageAvailableSemaphore[MAX_FRAMES_IN_FLIGHT];
VkSemaphore renderFinishedSemaphore; VkSemaphore renderFinishedSemaphore[MAX_FRAMES_IN_FLIGHT];
VkFence inFlightFence; VkFence inFlightFence[MAX_FRAMES_IN_FLIGHT];
uint32_t currentFrame; // initialised to 0
} Application; } Application;
typedef struct SwapChainSupportDetails { typedef struct SwapChainSupportDetails {
@ -976,9 +978,9 @@ void createCommandBuffer(Application *app) {
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
allocInfo.commandPool = app->commandPool; allocInfo.commandPool = app->commandPool;
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocInfo.commandBufferCount = 1; allocInfo.commandBufferCount = MAX_FRAMES_IN_FLIGHT;
if (vkAllocateCommandBuffers(app->device, &allocInfo, &app->commandBuffer) != if (vkAllocateCommandBuffers(app->device, &allocInfo, app->commandBuffers) !=
VK_SUCCESS) { VK_SUCCESS) {
fprintf(stderr, "Failed to allocate command buffers!"); fprintf(stderr, "Failed to allocate command buffers!");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -993,15 +995,17 @@ void createSyncObjects(Application *app) {
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
if (vkCreateSemaphore(app->device, &semaphoreInfo, NULL, if (vkCreateSemaphore(app->device, &semaphoreInfo, NULL,
&app->imageAvailableSemaphore) != VK_SUCCESS || &app->imageAvailableSemaphore[i]) != VK_SUCCESS ||
vkCreateSemaphore(app->device, &semaphoreInfo, NULL, vkCreateSemaphore(app->device, &semaphoreInfo, NULL,
&app->renderFinishedSemaphore) != VK_SUCCESS || &app->renderFinishedSemaphore[i]) != VK_SUCCESS ||
vkCreateFence(app->device, &fenceInfo, NULL, &app->inFlightFence) != vkCreateFence(app->device, &fenceInfo, NULL, &app->inFlightFence[i]) !=
VK_SUCCESS) { VK_SUCCESS) {
fprintf(stderr, "Failed to create semaphores!"); fprintf(stderr, "Failed to create semaphores!");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
}
} }
void initVulkan(Application *app) { void initVulkan(Application *app) {
@ -1021,32 +1025,32 @@ void initVulkan(Application *app) {
} }
void drawFrame(Application *app) { void drawFrame(Application *app) {
vkWaitForFences(app->device, 1, &app->inFlightFence, VK_TRUE, UINT64_MAX); vkWaitForFences(app->device, 1, &app->inFlightFence[app->currentFrame], VK_TRUE, UINT64_MAX);
vkResetFences(app->device, 1, &app->inFlightFence); vkResetFences(app->device, 1, &app->inFlightFence[app->currentFrame]);
uint32_t imageIndex; uint32_t imageIndex;
vkAcquireNextImageKHR(app->device, app->swapChain, UINT64_MAX, vkAcquireNextImageKHR(app->device, app->swapChain, UINT64_MAX,
app->imageAvailableSemaphore, VK_NULL_HANDLE, app->imageAvailableSemaphore[app->currentFrame], VK_NULL_HANDLE,
&imageIndex); &imageIndex);
vkResetCommandBuffer(app->commandBuffer, 0); vkResetCommandBuffer(app->commandBuffers[app->currentFrame], 0);
recordCommandBuffer(app, app->commandBuffer, imageIndex); recordCommandBuffer(app, app->commandBuffers[app->currentFrame], imageIndex);
VkSubmitInfo submitInfo = {0}; VkSubmitInfo submitInfo = {0};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
VkSemaphore waitSemaphores[] = {app->imageAvailableSemaphore}; VkSemaphore waitSemaphores[] = {app->imageAvailableSemaphore[app->currentFrame]};
VkPipelineStageFlags waitStages[] = { VkPipelineStageFlags waitStages[] = {
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
submitInfo.waitSemaphoreCount = 1; submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitSemaphores = waitSemaphores;
submitInfo.pWaitDstStageMask = waitStages; submitInfo.pWaitDstStageMask = waitStages;
submitInfo.commandBufferCount = 1; submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &app->commandBuffer; submitInfo.pCommandBuffers = &app->commandBuffers[app->currentFrame];
VkSemaphore signalSemaphores[] = {app->renderFinishedSemaphore}; VkSemaphore signalSemaphores[] = {app->renderFinishedSemaphore[app->currentFrame]};
submitInfo.signalSemaphoreCount = 1; submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = signalSemaphores; submitInfo.pSignalSemaphores = signalSemaphores;
if (vkQueueSubmit(app->graphicsQueue, 1, &submitInfo, app->inFlightFence) != if (vkQueueSubmit(app->graphicsQueue, 1, &submitInfo, app->inFlightFence[app->currentFrame]) !=
VK_SUCCESS) { VK_SUCCESS) {
fprintf(stderr, "failed to submit draw command buffer!"); fprintf(stderr, "failed to submit draw command buffer!");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -1063,6 +1067,8 @@ void drawFrame(Application *app) {
presentInfo.pResults = NULL; // Optional presentInfo.pResults = NULL; // Optional
vkQueuePresentKHR(app->presentQueue, &presentInfo); vkQueuePresentKHR(app->presentQueue, &presentInfo);
app->currentFrame = (app->currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
} }
void mainLoop(Application *app) { void mainLoop(Application *app) {
@ -1075,9 +1081,11 @@ void mainLoop(Application *app) {
} }
void cleanup(Application *app) { void cleanup(Application *app) {
vkDestroySemaphore(app->device, app->imageAvailableSemaphore, NULL); for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
vkDestroySemaphore(app->device, app->renderFinishedSemaphore, NULL); vkDestroySemaphore(app->device, app->imageAvailableSemaphore[i], NULL);
vkDestroyFence(app->device, app->inFlightFence, NULL); vkDestroySemaphore(app->device, app->renderFinishedSemaphore[i], NULL);
vkDestroyFence(app->device, app->inFlightFence[i], NULL);
}
vkDestroyCommandPool(app->device, app->commandPool, NULL); vkDestroyCommandPool(app->device, app->commandPool, NULL);
for (uint i = 0; i < app->swapChainFramebufferCount; i++) { for (uint i = 0; i < app->swapChainFramebufferCount; i++) {
vkDestroyFramebuffer(app->device, app->swapChainFramebuffers[i], NULL); vkDestroyFramebuffer(app->device, app->swapChainFramebuffers[i], NULL);