101 lines
3.6 KiB
C++
101 lines
3.6 KiB
C++
#include "HelloTriangleApplication.h"
|
|
|
|
void HelloTriangleApplication::createSyncObjects()
|
|
{
|
|
imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
|
|
renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
|
|
inFlightFences.resize(MAX_FRAMES_IN_FLIGHT);
|
|
imagesInFlight.resize(swapChainImages.size(), VK_NULL_HANDLE);
|
|
|
|
VkSemaphoreCreateInfo semaphoreInfo{};
|
|
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
|
|
|
VkFenceCreateInfo fenceInfo{};
|
|
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
|
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
|
|
|
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
|
|
{
|
|
if (vkCreateSemaphore(device, &semaphoreInfo, nullptr, &imageAvailableSemaphores[i]) != VK_SUCCESS ||
|
|
vkCreateSemaphore(device, &semaphoreInfo, nullptr, &renderFinishedSemaphores[i]) != VK_SUCCESS ||
|
|
vkCreateFence(device, &fenceInfo, nullptr, &inFlightFences[i]) != VK_SUCCESS)
|
|
{
|
|
throw std::runtime_error("failed to create synchronization objects for a frame!");
|
|
}
|
|
}
|
|
}
|
|
|
|
void HelloTriangleApplication::drawFrame()
|
|
{
|
|
vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
|
|
|
|
uint32_t imageIndex;
|
|
VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
|
|
|
|
if (result == VK_ERROR_OUT_OF_DATE_KHR)
|
|
{
|
|
recreateSwapChain();
|
|
return;
|
|
}
|
|
else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR)
|
|
{
|
|
throw std::runtime_error("failed to acquire swap chain image!");
|
|
}
|
|
|
|
// Check if a previous frame is using this image (i.e. there is its fence to wait on)
|
|
if (imagesInFlight[imageIndex] != VK_NULL_HANDLE)
|
|
{
|
|
vkWaitForFences(device, 1, &imagesInFlight[imageIndex], VK_TRUE, UINT64_MAX);
|
|
}
|
|
// Mark the image as now being in use by this frame
|
|
imagesInFlight[imageIndex] = inFlightFences[currentFrame];
|
|
|
|
VkSubmitInfo submitInfo{};
|
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
|
|
|
VkSemaphore waitSemaphores[] = {imageAvailableSemaphores[currentFrame]};
|
|
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
|
|
submitInfo.waitSemaphoreCount = 1;
|
|
submitInfo.pWaitSemaphores = waitSemaphores;
|
|
submitInfo.pWaitDstStageMask = waitStages;
|
|
|
|
submitInfo.commandBufferCount = 1;
|
|
submitInfo.pCommandBuffers = &commandBuffers[imageIndex];
|
|
|
|
VkSemaphore signalSemaphores[] = {renderFinishedSemaphores[currentFrame]};
|
|
submitInfo.signalSemaphoreCount = 1;
|
|
submitInfo.pSignalSemaphores = signalSemaphores;
|
|
|
|
vkResetFences(device, 1, &inFlightFences[currentFrame]);
|
|
|
|
if (vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame]) != VK_SUCCESS)
|
|
{
|
|
throw std::runtime_error("failed to submit draw command buffer!");
|
|
}
|
|
|
|
VkPresentInfoKHR presentInfo{};
|
|
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
|
|
|
presentInfo.waitSemaphoreCount = 1;
|
|
presentInfo.pWaitSemaphores = signalSemaphores;
|
|
|
|
VkSwapchainKHR swapChains[] = {swapChain};
|
|
presentInfo.swapchainCount = 1;
|
|
presentInfo.pSwapchains = swapChains;
|
|
|
|
presentInfo.pImageIndices = &imageIndex;
|
|
|
|
result = vkQueuePresentKHR(presentQueue, &presentInfo);
|
|
|
|
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || framebufferResized)
|
|
{
|
|
framebufferResized = false;
|
|
recreateSwapChain();
|
|
}
|
|
else if (result != VK_SUCCESS)
|
|
{
|
|
throw std::runtime_error("failed to present swap chain image!");
|
|
}
|
|
|
|
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
|
|
} |