完成swapchain随窗口大小改变重建
parent
dae58772e2
commit
c6d688a055
|
@ -22,12 +22,14 @@ const bool enableValidationLayers = true;
|
||||||
#endif // NDEBUG
|
#endif // NDEBUG
|
||||||
|
|
||||||
//window init
|
//window init
|
||||||
GLFWwindow* HelloTriangleApplication::initWindow(int Width, int Height) {
|
void HelloTriangleApplication::initWindow(int Width, int Height) {
|
||||||
glfwInit();
|
glfwInit();
|
||||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
|
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
|
||||||
window = glfwCreateWindow(Width, Height, "vulkan", nullptr, nullptr);
|
window = glfwCreateWindow(Width, Height, "vulkan", nullptr, nullptr);
|
||||||
return window;
|
glfwSetWindowUserPointer(window, this);
|
||||||
|
glfwSetFramebufferSizeCallback(window, framebufferResizeCallback);
|
||||||
|
|
||||||
}
|
}
|
||||||
// vulkan instace create
|
// vulkan instace create
|
||||||
void HelloTriangleApplication::createInstance() {
|
void HelloTriangleApplication::createInstance() {
|
||||||
|
@ -110,7 +112,7 @@ void HelloTriangleApplication::initVulkan() {
|
||||||
|
|
||||||
createSwapChain();
|
createSwapChain();
|
||||||
|
|
||||||
creatImageView();
|
createImageView();
|
||||||
|
|
||||||
createRenderPass();
|
createRenderPass();
|
||||||
createGraphicPipeline();
|
createGraphicPipeline();
|
||||||
|
@ -143,38 +145,32 @@ void HelloTriangleApplication::mainLoop(GLFWwindow* window){
|
||||||
|
|
||||||
void HelloTriangleApplication::cleanup(GLFWwindow* window) {
|
void HelloTriangleApplication::cleanup(GLFWwindow* window) {
|
||||||
|
|
||||||
std::cout << "\nstart to destroy resource\n" << std::endl;
|
std::cout << "\n======== start to destroy resource ========\n" << std::endl;
|
||||||
|
|
||||||
vkDestroySemaphore(device, imageAvailableSemaphore, nullptr);
|
cleanupSwapChain();
|
||||||
vkDestroySemaphore(device, renderFinishedSemaphore, nullptr);
|
|
||||||
vkDestroyFence(device, inFlightFence, nullptr);
|
|
||||||
|
|
||||||
vkDestroyCommandPool(device, commandPool, nullptr);
|
|
||||||
|
|
||||||
for (auto framebuffer : swapChainFramebuffers)
|
|
||||||
{
|
|
||||||
vkDestroyFramebuffer(device, framebuffer, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
vkDestroyPipeline(device, graphicsPipeline, nullptr);
|
vkDestroyPipeline(device, graphicsPipeline, nullptr);
|
||||||
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
|
||||||
vkDestroyRenderPass(device, renderPass, nullptr);
|
vkDestroyRenderPass(device, renderPass, nullptr);
|
||||||
|
|
||||||
for (auto imageView : swapChainImageViews)
|
for (size_t i = 0; i < MAX_FRAME_IN_FLIGHT; i++)
|
||||||
{
|
{
|
||||||
vkDestroyImageView(device, imageView, nullptr);
|
vkDestroySemaphore(device, imageAvailableSemaphores[i], nullptr);
|
||||||
|
vkDestroySemaphore(device, renderFinishedSemaphores[i], nullptr);
|
||||||
|
vkDestroyFence(device, inFlightFences[i], nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
vkDestroySwapchainKHR(device, swapChain, nullptr);
|
|
||||||
|
|
||||||
vkDestroySurfaceKHR(instance, surface, nullptr);
|
vkDestroyCommandPool(device, commandPool, nullptr);
|
||||||
|
|
||||||
|
vkDestroyDevice(device, nullptr);
|
||||||
|
|
||||||
if (enableValidationLayers)
|
if (enableValidationLayers)
|
||||||
{
|
{
|
||||||
DestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr);
|
DestroyDebugUtilsMessengerEXT(instance, debugMessenger, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
vkDestroyDevice(device, nullptr);
|
vkDestroySurfaceKHR(instance, surface, nullptr);
|
||||||
|
|
||||||
vkDestroyInstance(instance, nullptr);
|
vkDestroyInstance(instance, nullptr);
|
||||||
|
|
||||||
|
@ -561,7 +557,47 @@ void HelloTriangleApplication::createSwapChain()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HelloTriangleApplication::creatImageView()
|
void HelloTriangleApplication::cleanupSwapChain()
|
||||||
|
{
|
||||||
|
for (auto framebuffer : swapChainFramebuffers)
|
||||||
|
{
|
||||||
|
vkDestroyFramebuffer(device, framebuffer, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto imageView : swapChainImageViews)
|
||||||
|
{
|
||||||
|
vkDestroyImageView(device, imageView, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
vkDestroySwapchainKHR(device, swapChain, nullptr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void HelloTriangleApplication::recreateSwapChain()
|
||||||
|
{
|
||||||
|
|
||||||
|
int width = 0, height = 0;
|
||||||
|
glfwGetFramebufferSize(window, &width, &height);
|
||||||
|
while (width == 0 || height == 0)
|
||||||
|
{
|
||||||
|
if (glfwWindowShouldClose(window))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
glfwGetFramebufferSize(window, &width, &height);
|
||||||
|
glfwWaitEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
vkDeviceWaitIdle(device);
|
||||||
|
|
||||||
|
cleanupSwapChain();
|
||||||
|
|
||||||
|
createSwapChain();
|
||||||
|
createImageView();
|
||||||
|
creatFramebuffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HelloTriangleApplication::createImageView()
|
||||||
{
|
{
|
||||||
swapChainImageViews.resize(swapChainImages.size());
|
swapChainImageViews.resize(swapChainImages.size());
|
||||||
|
|
||||||
|
@ -673,13 +709,15 @@ void HelloTriangleApplication::createCommandPool()
|
||||||
|
|
||||||
void HelloTriangleApplication::createCommandBuffer()
|
void HelloTriangleApplication::createCommandBuffer()
|
||||||
{
|
{
|
||||||
|
commandBuffers.resize(MAX_FRAME_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 in createCommandBuffer");
|
throw std::runtime_error("failed to allocate command buffers in createCommandBuffer");
|
||||||
}
|
}
|
||||||
|
@ -737,33 +775,46 @@ void HelloTriangleApplication::recordCommandBuffer(VkCommandBuffer commandBuffer
|
||||||
|
|
||||||
void HelloTriangleApplication::drawFrame()
|
void HelloTriangleApplication::drawFrame()
|
||||||
{
|
{
|
||||||
//等待所有fence收到信号后返回,uint64_max禁用超时
|
uint32_t currentFrame = 0;
|
||||||
vkWaitForFences(device, 1, &inFlightFence, VK_TRUE, UINT64_MAX);
|
|
||||||
|
|
||||||
vkResetFences(device, 1, &inFlightFence);
|
|
||||||
|
|
||||||
uint32_t imageIndex;
|
uint32_t imageIndex;
|
||||||
vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex);
|
//等待所有fence收到信号后返回,uint64_max禁用超时
|
||||||
|
vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
|
||||||
|
|
||||||
vkResetCommandBuffer(commandBuffer, 0);
|
VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
|
||||||
recordCommandBuffer(commandBuffer, 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 in drawFrame");
|
||||||
|
}
|
||||||
|
|
||||||
|
vkResetFences(device, 1, &inFlightFences[currentFrame]);
|
||||||
|
|
||||||
|
//vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
|
||||||
|
|
||||||
|
vkResetCommandBuffer(commandBuffers[currentFrame], 0);
|
||||||
|
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 signalSemaphores[] = { renderFinishedSemaphore };
|
VkSemaphore signalSemaphores[] = { renderFinishedSemaphores[currentFrame]};
|
||||||
submitInfo.signalSemaphoreCount = 1;
|
submitInfo.signalSemaphoreCount = 1;
|
||||||
submitInfo.pSignalSemaphores = signalSemaphores;
|
submitInfo.pSignalSemaphores = signalSemaphores;
|
||||||
|
|
||||||
if (vkQueueSubmit(graphicQueue,1,&submitInfo,inFlightFence) != VK_SUCCESS)
|
if (vkQueueSubmit(graphicQueue,1,&submitInfo,inFlightFences[currentFrame]) != VK_SUCCESS)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("failed to submit draw command buffer in drawFrame");
|
throw std::runtime_error("failed to submit draw command buffer in drawFrame");
|
||||||
}
|
}
|
||||||
|
@ -779,12 +830,29 @@ void HelloTriangleApplication::drawFrame()
|
||||||
presentInfo.pSwapchains = swapChains;
|
presentInfo.pSwapchains = swapChains;
|
||||||
presentInfo.pImageIndices = &imageIndex;
|
presentInfo.pImageIndices = &imageIndex;
|
||||||
presentInfo.pResults = nullptr;
|
presentInfo.pResults = nullptr;
|
||||||
vkQueuePresentKHR(presentQueue, &presentInfo);
|
//vkQueuePresentKHR(presentQueue, &presentInfo);
|
||||||
|
|
||||||
|
result = vkQueuePresentKHR(presentQueue, &presentInfo);
|
||||||
|
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
|
||||||
|
{
|
||||||
|
framebufferResized = false;
|
||||||
|
recreateSwapChain();
|
||||||
|
}
|
||||||
|
else if (result != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("failed to present swap chain image in drawFrame");
|
||||||
|
}
|
||||||
|
|
||||||
|
currentFrame = (currentFrame + 1) % MAX_FRAME_IN_FLIGHT;//前进下一帧
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HelloTriangleApplication::createSyncObjects()
|
void HelloTriangleApplication::createSyncObjects()
|
||||||
{
|
{
|
||||||
|
imageAvailableSemaphores.resize(MAX_FRAME_IN_FLIGHT);
|
||||||
|
renderFinishedSemaphores.resize(MAX_FRAME_IN_FLIGHT);
|
||||||
|
inFlightFences.resize(MAX_FRAME_IN_FLIGHT);
|
||||||
|
|
||||||
VkSemaphoreCreateInfo semaphoreInfo{};
|
VkSemaphoreCreateInfo semaphoreInfo{};
|
||||||
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||||
|
|
||||||
|
@ -792,15 +860,22 @@ void HelloTriangleApplication::createSyncObjects()
|
||||||
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||||
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;//防止vkWaitForFences在第一帧无限期阻塞
|
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;//防止vkWaitForFences在第一帧无限期阻塞
|
||||||
|
|
||||||
if (vkCreateSemaphore(device,&semaphoreInfo,nullptr,&imageAvailableSemaphore) != VK_SUCCESS ||
|
if (vkCreateSemaphore(device,&semaphoreInfo,nullptr,imageAvailableSemaphores.data()) != VK_SUCCESS ||
|
||||||
vkCreateSemaphore(device, &semaphoreInfo, nullptr, &renderFinishedSemaphore) != VK_SUCCESS ||
|
vkCreateSemaphore(device, &semaphoreInfo, nullptr, renderFinishedSemaphores.data()) != VK_SUCCESS ||
|
||||||
vkCreateFence(device,&fenceInfo,nullptr,&inFlightFence) != VK_SUCCESS)
|
vkCreateFence(device,&fenceInfo,nullptr,inFlightFences.data()) != VK_SUCCESS)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("failed to create semaphores in creatSyncObjects");
|
throw std::runtime_error("failed to create semaphores in creatSyncObjects");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HelloTriangleApplication::framebufferResizeCallback(GLFWwindow* window, int width, int height)
|
||||||
|
{
|
||||||
|
auto app = reinterpret_cast<HelloTriangleApplication*>(glfwGetWindowUserPointer(window));
|
||||||
|
app->framebufferResized = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void HelloTriangleApplication::createRenderPass()
|
void HelloTriangleApplication::createRenderPass()
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,10 +30,12 @@ class HelloTriangleApplication
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
const int MAX_FRAME_IN_FLIGHT = 2;
|
||||||
|
|
||||||
HelloTriangleApplication();
|
HelloTriangleApplication();
|
||||||
~HelloTriangleApplication();
|
~HelloTriangleApplication();
|
||||||
void run(int Width, int Height) {
|
void run(int Width, int Height) {
|
||||||
GLFWwindow* window = initWindow(Width,Height);
|
initWindow(Width,Height);
|
||||||
initVulkan();
|
initVulkan();
|
||||||
mainLoop(window);
|
mainLoop(window);
|
||||||
cleanup(window);
|
cleanup(window);
|
||||||
|
@ -68,9 +70,7 @@ private:
|
||||||
|
|
||||||
VkPipeline graphicsPipeline;
|
VkPipeline graphicsPipeline;
|
||||||
|
|
||||||
VkSemaphore imageAvailableSemaphore;
|
|
||||||
VkSemaphore renderFinishedSemaphore;
|
|
||||||
VkFence inFlightFence;
|
|
||||||
|
|
||||||
struct QueueFamilyIndices
|
struct QueueFamilyIndices
|
||||||
{
|
{
|
||||||
|
@ -93,9 +93,15 @@ private:
|
||||||
|
|
||||||
VkCommandPool commandPool;
|
VkCommandPool commandPool;
|
||||||
|
|
||||||
VkCommandBuffer commandBuffer;
|
std::vector<VkCommandBuffer> commandBuffers;
|
||||||
|
|
||||||
GLFWwindow* initWindow(int Width, int Height);
|
std::vector<VkSemaphore> imageAvailableSemaphores;
|
||||||
|
std::vector<VkSemaphore> renderFinishedSemaphores;
|
||||||
|
std::vector<VkFence> inFlightFences;
|
||||||
|
|
||||||
|
bool framebufferResized = false;
|
||||||
|
|
||||||
|
void initWindow(int Width, int Height);
|
||||||
|
|
||||||
void createInstance();
|
void createInstance();
|
||||||
|
|
||||||
|
@ -137,8 +143,10 @@ private:
|
||||||
VkPresentModeKHR chooseSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes);
|
VkPresentModeKHR chooseSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes);
|
||||||
VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities);
|
VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities);
|
||||||
void createSwapChain();
|
void createSwapChain();
|
||||||
|
void cleanupSwapChain();
|
||||||
|
void recreateSwapChain();
|
||||||
|
|
||||||
void creatImageView();
|
void createImageView();
|
||||||
|
|
||||||
void createRenderPass();
|
void createRenderPass();
|
||||||
void createGraphicPipeline();
|
void createGraphicPipeline();
|
||||||
|
@ -159,6 +167,8 @@ private:
|
||||||
|
|
||||||
void createSyncObjects();
|
void createSyncObjects();
|
||||||
|
|
||||||
|
static void framebufferResizeCallback(GLFWwindow* window, int width, int height);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HelloTriangleApplication::HelloTriangleApplication()
|
HelloTriangleApplication::HelloTriangleApplication()
|
||||||
|
|
Loading…
Reference in New Issue