@@ -162,6 +162,8 @@ class HelloTriangleApplication {
162162 void initWindow () {
163163 glfwInit ();
164164 glfwWindowHint (GLFW_CLIENT_API, GLFW_NO_API);
165+ glfwWindowHint (GLFW_RESIZABLE, GLFW_TRUE);
166+
165167 window = glfwCreateWindow (WIDTH, HEIGHT, " Vulkan Profiles Demo" , nullptr , nullptr );
166168 glfwSetWindowUserPointer (window, this );
167169 glfwSetFramebufferSizeCallback (window, framebufferResizeCallback);
@@ -221,23 +223,11 @@ class HelloTriangleApplication {
221223 }
222224
223225 void cleanupSwapChain () {
224- colorImageView = nullptr ;
225- colorImage = nullptr ;
226- colorImageMemory = nullptr ;
227-
228- depthImageView = nullptr ;
229- depthImage = nullptr ;
230- depthImageMemory = nullptr ;
231-
232- for (auto & framebuffer : swapChainFramebuffers) {
233- framebuffer = nullptr ;
234- }
226+ swapChainFramebuffers.clear ();
227+ swapChainImageViews.clear ();
235228
236- for (auto & imageView : swapChainImageViews) {
237- imageView = nullptr ;
238- }
239-
240- swapChain = nullptr ;
229+ // Semaphores tied to swapchain image indices need to be rebuilt on resize
230+ presentCompleteSemaphore.clear ();
241231 }
242232
243233 void cleanup () {
@@ -268,6 +258,13 @@ class HelloTriangleApplication {
268258
269259 createColorResources ();
270260 createDepthResources ();
261+
262+ // Recreate per-swapchain-image present semaphores after resize
263+ presentCompleteSemaphore.reserve (swapChainImages.size ());
264+ vk::SemaphoreCreateInfo semaphoreInfo{};
265+ for (size_t i = 0 ; i < swapChainImages.size (); ++i) {
266+ presentCompleteSemaphore.push_back (device.createSemaphore (semaphoreInfo));
267+ }
271268 }
272269
273270 void createInstance () {
@@ -1338,8 +1335,45 @@ class HelloTriangleApplication {
13381335 void recordCommandBuffer (uint32_t imageIndex) {
13391336 commandBuffers[currentFrame].begin ({});
13401337
1341- // Transition the swapchain image to the correct layout for rendering
1342- vk::ImageMemoryBarrier imageBarrier{
1338+ // Transition the attachments to the correct layouts for dynamic rendering
1339+ // 1) Multisampled color attachment image -> ColorAttachmentOptimal
1340+ vk::ImageMemoryBarrier colorAttachmentBarrier{
1341+ .srcAccessMask = vk::AccessFlagBits::eNone,
1342+ .dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite,
1343+ .oldLayout = vk::ImageLayout::eUndefined,
1344+ .newLayout = vk::ImageLayout::eColorAttachmentOptimal,
1345+ .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
1346+ .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
1347+ .image = *colorImage,
1348+ .subresourceRange = {
1349+ .aspectMask = vk::ImageAspectFlagBits::eColor,
1350+ .baseMipLevel = 0 ,
1351+ .levelCount = 1 ,
1352+ .baseArrayLayer = 0 ,
1353+ .layerCount = 1
1354+ }
1355+ };
1356+
1357+ // 2) Depth attachment image -> DepthStencilAttachmentOptimal
1358+ vk::ImageMemoryBarrier depthAttachmentBarrier{
1359+ .srcAccessMask = vk::AccessFlagBits::eNone,
1360+ .dstAccessMask = vk::AccessFlagBits::eDepthStencilAttachmentWrite,
1361+ .oldLayout = vk::ImageLayout::eUndefined,
1362+ .newLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal,
1363+ .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
1364+ .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
1365+ .image = *depthImage,
1366+ .subresourceRange = {
1367+ .aspectMask = vk::ImageAspectFlagBits::eDepth,
1368+ .baseMipLevel = 0 ,
1369+ .levelCount = 1 ,
1370+ .baseArrayLayer = 0 ,
1371+ .layerCount = 1
1372+ }
1373+ };
1374+
1375+ // 3) Resolve (swapchain) image -> ColorAttachmentOptimal
1376+ vk::ImageMemoryBarrier swapchainResolveBarrier{
13431377 .srcAccessMask = vk::AccessFlagBits::eNone,
13441378 .dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite,
13451379 .oldLayout = vk::ImageLayout::eUndefined,
@@ -1358,11 +1392,11 @@ class HelloTriangleApplication {
13581392
13591393 commandBuffers[currentFrame].pipelineBarrier (
13601394 vk::PipelineStageFlagBits::eTopOfPipe,
1361- vk::PipelineStageFlagBits::eColorAttachmentOutput,
1395+ vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eEarlyFragmentTests ,
13621396 vk::DependencyFlagBits::eByRegion,
13631397 std::array<vk::MemoryBarrier, 0 >{},
13641398 std::array<vk::BufferMemoryBarrier, 0 >{},
1365- std::array<vk::ImageMemoryBarrier, 1 >{imageBarrier }
1399+ std::array<vk::ImageMemoryBarrier, 3 >{colorAttachmentBarrier, depthAttachmentBarrier, swapchainResolveBarrier }
13661400 );
13671401
13681402 // Clear values for color and depth
@@ -1548,28 +1582,29 @@ class HelloTriangleApplication {
15481582 };
15491583 queue.submit (submitInfo, *inFlightFences[currentFrame]);
15501584
1551- const vk::PresentInfoKHR presentInfoKHR{
1552- .waitSemaphoreCount = 1 ,
1553- .pWaitSemaphores = &*presentCompleteSemaphore[imageIndex],
1554- .swapchainCount = 1 ,
1555- .pSwapchains = &*swapChain,
1556- .pImageIndices = &imageIndex
1557- };
1558-
1559- vk::Result result;
15601585 try {
1561- result = queue.presentKHR (presentInfoKHR);
1562- } catch (vk::OutOfDateKHRError&) {
1563- result = vk::Result::eErrorOutOfDateKHR;
1564- }
1565-
1566- if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized) {
1567- framebufferResized = false ;
1568- recreateSwapChain ();
1569- } else if (result != vk::Result::eSuccess) {
1570- throw std::runtime_error (" failed to present swap chain image!" );
1586+ const vk::PresentInfoKHR presentInfoKHR{
1587+ .waitSemaphoreCount = 1 ,
1588+ .pWaitSemaphores = &*presentCompleteSemaphore[imageIndex],
1589+ .swapchainCount = 1 ,
1590+ .pSwapchains = &*swapChain,
1591+ .pImageIndices = &imageIndex
1592+ };
1593+ auto result = queue.presentKHR (presentInfoKHR);
1594+ if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR || framebufferResized) {
1595+ framebufferResized = false ;
1596+ recreateSwapChain ();
1597+ } else if (result != vk::Result::eSuccess) {
1598+ throw std::runtime_error (" failed to present swap chain image!" );
1599+ }
1600+ } catch (const vk::SystemError& e) {
1601+ if (e.code ().value () == static_cast <int >(vk::Result::eErrorOutOfDateKHR)) {
1602+ recreateSwapChain ();
1603+ return ;
1604+ } else {
1605+ throw ;
1606+ }
15711607 }
1572-
15731608 currentFrame = (currentFrame + 1 ) % MAX_FRAMES_IN_FLIGHT;
15741609 }
15751610
0 commit comments