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