2 Frames in flight
This commit is contained in:
@@ -17,9 +17,9 @@
|
||||
#include <set>
|
||||
#include <fstream>
|
||||
|
||||
|
||||
const uint32_t WIDTH = 800;
|
||||
const uint32_t HEIGHT = 600;
|
||||
const int MAX_FRAMES_IN_FLIGHT = 2;
|
||||
|
||||
const std::vector<const char*> validationLayers ={
|
||||
"VK_LAYER_KHRONOS_validation"
|
||||
@@ -65,12 +65,12 @@ const std::vector<const char*> deviceExtensions = {
|
||||
VkPipeline graphicsPipeline;
|
||||
std::vector<VkFramebuffer> swapchainFrameBuffers;
|
||||
VkCommandPool commandPool;
|
||||
VkCommandBuffer commandBuffer;
|
||||
VkSemaphore imageAvailableSemaphore;
|
||||
VkSemaphore renderFinishedSemaphore;
|
||||
VkFence inFlightFence;
|
||||
|
||||
std::vector<VkCommandBuffer> commandBuffers;
|
||||
std::vector<VkSemaphore> imageAvailableSemaphores;
|
||||
std::vector<VkSemaphore> renderFinishedSemaphores;
|
||||
std::vector<VkFence> inFlightFences;
|
||||
|
||||
uint32_t currentFrame = 0;
|
||||
|
||||
struct SwapChainSupportDetails {
|
||||
VkSurfaceCapabilitiesKHR capabilities;
|
||||
@@ -100,11 +100,15 @@ const std::vector<const char*> deviceExtensions = {
|
||||
createGraphicsPipeline();
|
||||
createFramebuffers();
|
||||
createCommandPool();
|
||||
createCommandBuffer();
|
||||
createCommandBuffers();
|
||||
createSyncObjects();
|
||||
}
|
||||
|
||||
void createSyncObjects() {
|
||||
imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
|
||||
renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
|
||||
inFlightFences.resize(MAX_FRAMES_IN_FLIGHT);
|
||||
|
||||
VkSemaphoreCreateInfo semaphoreInfo{};
|
||||
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
|
||||
@@ -112,12 +116,17 @@ const std::vector<const char*> deviceExtensions = {
|
||||
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||
|
||||
if (vkCreateSemaphore(device, &semaphoreInfo, nullptr, &imageAvailableSemaphore) != VK_SUCCESS ||
|
||||
vkCreateSemaphore(device, &semaphoreInfo, nullptr, &renderFinishedSemaphore) != VK_SUCCESS ||
|
||||
vkCreateFence(device, &fenceInfo, nullptr, &inFlightFence) != VK_SUCCESS) {
|
||||
throw std::runtime_error("failed to create semaphores!");
|
||||
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 semaphores!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -169,14 +178,16 @@ const std::vector<const char*> deviceExtensions = {
|
||||
|
||||
}
|
||||
|
||||
void createCommandBuffer() {
|
||||
void createCommandBuffers() {
|
||||
commandBuffers.resize(MAX_FRAMES_IN_FLIGHT);
|
||||
|
||||
VkCommandBufferAllocateInfo allocInfo{};
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
allocInfo.commandPool = commandPool;
|
||||
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
allocInfo.commandBufferCount = 1;
|
||||
allocInfo.commandBufferCount = (uint32_t) commandBuffers.size();
|
||||
|
||||
if (vkAllocateCommandBuffers(device, &allocInfo, &commandBuffer) != VK_SUCCESS) {
|
||||
if (vkAllocateCommandBuffers(device, &allocInfo, commandBuffers.data()) != VK_SUCCESS) {
|
||||
throw std::runtime_error("failed to allocate command buffers!");
|
||||
}
|
||||
}
|
||||
@@ -559,7 +570,6 @@ const std::vector<const char*> deviceExtensions = {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
void pickPhysicalDevice() {
|
||||
uint32_t deviceCount = 0;
|
||||
vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
|
||||
@@ -675,7 +685,6 @@ const std::vector<const char*> deviceExtensions = {
|
||||
return details;
|
||||
}
|
||||
|
||||
|
||||
VkResult CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pDebugMessenger) {
|
||||
auto func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
|
||||
if (func != nullptr) {
|
||||
@@ -739,7 +748,6 @@ const std::vector<const char*> deviceExtensions = {
|
||||
return requiredExtensions.empty();
|
||||
}
|
||||
|
||||
|
||||
std::vector<const char*> getRequiredExtensions() {
|
||||
uint32_t glfwExtensionCount = 0;
|
||||
const char** glfwExtensions;
|
||||
@@ -857,34 +865,33 @@ const std::vector<const char*> deviceExtensions = {
|
||||
vkDeviceWaitIdle(device);
|
||||
}
|
||||
|
||||
|
||||
void drawFrame() {
|
||||
vkWaitForFences(device, 1, &inFlightFence, VK_TRUE, UINT64_MAX);
|
||||
vkResetFences(device, 1, &inFlightFence);
|
||||
vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
|
||||
vkResetFences(device, 1, &inFlightFences[currentFrame]);
|
||||
|
||||
uint32_t imageIndex;
|
||||
vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex);
|
||||
vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
|
||||
|
||||
vkResetCommandBuffer(commandBuffer, 0);
|
||||
recordCommandBuffer(commandBuffer, imageIndex);
|
||||
vkResetCommandBuffer(commandBuffers[currentFrame], 0);
|
||||
recordCommandBuffer(commandBuffers[currentFrame], imageIndex);
|
||||
|
||||
VkSubmitInfo submitInfo{};
|
||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
|
||||
VkSemaphore waitSemaphores[] = { imageAvailableSemaphore };
|
||||
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 = &commandBuffer;
|
||||
submitInfo.pCommandBuffers = &commandBuffers[currentFrame];
|
||||
|
||||
VkSemaphore signalSemaphore[] = { renderFinishedSemaphore };
|
||||
VkSemaphore signalSemaphore[] = { renderFinishedSemaphores[currentFrame]};
|
||||
submitInfo.signalSemaphoreCount = 1;
|
||||
submitInfo.pSignalSemaphores = signalSemaphore;
|
||||
|
||||
if (vkQueueSubmit(graphicsQueue,1, &submitInfo, inFlightFence) != VK_SUCCESS) {
|
||||
if (vkQueueSubmit(graphicsQueue,1, &submitInfo, inFlightFences[currentFrame]) != VK_SUCCESS) {
|
||||
throw std::runtime_error("failed to submit draw command buffer");
|
||||
}
|
||||
|
||||
@@ -901,17 +908,18 @@ const std::vector<const char*> deviceExtensions = {
|
||||
|
||||
vkQueuePresentKHR(presentQueue, &presentInfo);
|
||||
|
||||
|
||||
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void cleanup(){
|
||||
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
|
||||
vkDestroySemaphore(device, imageAvailableSemaphores[i], nullptr);
|
||||
vkDestroySemaphore(device, renderFinishedSemaphores[i], nullptr);
|
||||
vkDestroyFence(device, inFlightFences[i], nullptr);
|
||||
|
||||
vkDestroySemaphore(device, imageAvailableSemaphore, nullptr);
|
||||
vkDestroySemaphore(device, renderFinishedSemaphore, nullptr);
|
||||
vkDestroyFence(device, inFlightFence, nullptr);
|
||||
}
|
||||
|
||||
vkDestroyCommandPool(device, commandPool, nullptr);
|
||||
|
||||
@@ -951,7 +959,6 @@ const std::vector<const char*> deviceExtensions = {
|
||||
createInfo.pfnUserCallback = debugCallback;
|
||||
}
|
||||
|
||||
|
||||
void DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks* pAllocator) {
|
||||
auto func = (PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT");
|
||||
if (func != nullptr) {
|
||||
|
||||
Reference in New Issue
Block a user