@@ -181,6 +181,7 @@ class HelloTriangleApplication {
181181 setupDebugMessenger ();
182182 createSurface ();
183183 pickPhysicalDevice ();
184+ msaaSamples = getMaxUsableSampleCount ();
184185 createLogicalDevice ();
185186 createSwapChain ();
186187 createImageViews ();
@@ -528,7 +529,12 @@ class HelloTriangleApplication {
528529
529530 pipelineLayout = vk::raii::PipelineLayout (device, pipelineLayoutInfo);
530531
531- vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{ .colorAttachmentCount = 1 , .pColorAttachmentFormats = &swapChainImageFormat };
532+ vk::Format depthFormat = findDepthFormat ();
533+ vk::PipelineRenderingCreateInfo pipelineRenderingCreateInfo{
534+ .colorAttachmentCount = 1 ,
535+ .pColorAttachmentFormats = &swapChainImageFormat,
536+ .depthAttachmentFormat = depthFormat
537+ };
532538 vk::GraphicsPipelineCreateInfo pipelineInfo{ .pNext = &pipelineRenderingCreateInfo,
533539 .stageCount = 2 ,
534540 .pStages = shaderStages,
@@ -1019,7 +1025,8 @@ class HelloTriangleApplication {
10191025
10201026 void recordCommandBuffer (uint32_t imageIndex) {
10211027 commandBuffers[currentFrame].begin ({});
1022- // Before starting rendering, transition the swapchain image to COLOR_ATTACHMENT_OPTIMAL
1028+ // Before starting rendering, transition the images to the appropriate layouts
1029+ // Transition the swapchain image to COLOR_ATTACHMENT_OPTIMAL
10231030 transition_image_layout (
10241031 imageIndex,
10251032 vk::ImageLayout::eUndefined,
@@ -1029,19 +1036,60 @@ class HelloTriangleApplication {
10291036 vk::PipelineStageFlagBits2::eTopOfPipe, // srcStage
10301037 vk::PipelineStageFlagBits2::eColorAttachmentOutput // dstStage
10311038 );
1039+
1040+ // Transition the multisampled color image to COLOR_ATTACHMENT_OPTIMAL
1041+ transition_image_layout_custom (
1042+ colorImage,
1043+ vk::ImageLayout::eUndefined,
1044+ vk::ImageLayout::eColorAttachmentOptimal,
1045+ {},
1046+ vk::AccessFlagBits2::eColorAttachmentWrite,
1047+ vk::PipelineStageFlagBits2::eTopOfPipe,
1048+ vk::PipelineStageFlagBits2::eColorAttachmentOutput,
1049+ vk::ImageAspectFlagBits::eColor
1050+ );
1051+
1052+ // Transition the depth image to DEPTH_ATTACHMENT_OPTIMAL
1053+ transition_image_layout_custom (
1054+ depthImage,
1055+ vk::ImageLayout::eUndefined,
1056+ vk::ImageLayout::eDepthAttachmentOptimal,
1057+ {},
1058+ vk::AccessFlagBits2::eDepthStencilAttachmentWrite,
1059+ vk::PipelineStageFlagBits2::eTopOfPipe,
1060+ vk::PipelineStageFlagBits2::eEarlyFragmentTests,
1061+ vk::ImageAspectFlagBits::eDepth
1062+ );
10321063 vk::ClearValue clearColor = vk::ClearColorValue (0 .0f , 0 .0f , 0 .0f , 1 .0f );
1033- vk::RenderingAttachmentInfo attachmentInfo = {
1034- .imageView = swapChainImageViews[imageIndex],
1064+ vk::ClearValue clearDepth = vk::ClearDepthStencilValue (1 .0f , 0 );
1065+
1066+ // Color attachment (multisampled) with resolve attachment
1067+ vk::RenderingAttachmentInfo colorAttachment = {
1068+ .imageView = colorImageView,
10351069 .imageLayout = vk::ImageLayout::eColorAttachmentOptimal,
1070+ .resolveMode = vk::ResolveModeFlagBits::eAverage,
1071+ .resolveImageView = swapChainImageViews[imageIndex],
1072+ .resolveImageLayout = vk::ImageLayout::eColorAttachmentOptimal,
10361073 .loadOp = vk::AttachmentLoadOp::eClear,
10371074 .storeOp = vk::AttachmentStoreOp::eStore,
10381075 .clearValue = clearColor
10391076 };
1077+
1078+ // Depth attachment
1079+ vk::RenderingAttachmentInfo depthAttachment = {
1080+ .imageView = depthImageView,
1081+ .imageLayout = vk::ImageLayout::eDepthAttachmentOptimal,
1082+ .loadOp = vk::AttachmentLoadOp::eClear,
1083+ .storeOp = vk::AttachmentStoreOp::eDontCare,
1084+ .clearValue = clearDepth
1085+ };
1086+
10401087 vk::RenderingInfo renderingInfo = {
10411088 .renderArea = { .offset = { 0 , 0 }, .extent = swapChainExtent },
10421089 .layerCount = 1 ,
10431090 .colorAttachmentCount = 1 ,
1044- .pColorAttachments = &attachmentInfo
1091+ .pColorAttachments = &colorAttachment,
1092+ .pDepthAttachment = &depthAttachment
10451093 };
10461094 commandBuffers[currentFrame].beginRendering (renderingInfo);
10471095 commandBuffers[currentFrame].bindPipeline (vk::PipelineBindPoint::eGraphics, *graphicsPipeline);
@@ -1052,7 +1100,9 @@ class HelloTriangleApplication {
10521100 commandBuffers[currentFrame].bindDescriptorSets (vk::PipelineBindPoint::eGraphics, pipelineLayout, 0 , *descriptorSets[currentFrame], nullptr );
10531101 commandBuffers[currentFrame].drawIndexed (indices.size (), 1 , 0 , 0 , 0 );
10541102 commandBuffers[currentFrame].endRendering ();
1055- // After rendering, transition the swapchain image to PRESENT_SRC
1103+ // After rendering, transition the images to appropriate layouts
1104+
1105+ // Transition the swapchain image to PRESENT_SRC
10561106 transition_image_layout (
10571107 imageIndex,
10581108 vk::ImageLayout::eColorAttachmentOptimal,
@@ -1100,6 +1150,42 @@ class HelloTriangleApplication {
11001150 commandBuffers[currentFrame].pipelineBarrier2 (dependency_info);
11011151 }
11021152
1153+ void transition_image_layout_custom (
1154+ vk::raii::Image& image,
1155+ vk::ImageLayout old_layout,
1156+ vk::ImageLayout new_layout,
1157+ vk::AccessFlags2 src_access_mask,
1158+ vk::AccessFlags2 dst_access_mask,
1159+ vk::PipelineStageFlags2 src_stage_mask,
1160+ vk::PipelineStageFlags2 dst_stage_mask,
1161+ vk::ImageAspectFlags aspect_mask
1162+ ) {
1163+ vk::ImageMemoryBarrier2 barrier = {
1164+ .srcStageMask = src_stage_mask,
1165+ .srcAccessMask = src_access_mask,
1166+ .dstStageMask = dst_stage_mask,
1167+ .dstAccessMask = dst_access_mask,
1168+ .oldLayout = old_layout,
1169+ .newLayout = new_layout,
1170+ .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
1171+ .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
1172+ .image = image,
1173+ .subresourceRange = {
1174+ .aspectMask = aspect_mask,
1175+ .baseMipLevel = 0 ,
1176+ .levelCount = 1 ,
1177+ .baseArrayLayer = 0 ,
1178+ .layerCount = 1
1179+ }
1180+ };
1181+ vk::DependencyInfo dependency_info = {
1182+ .dependencyFlags = {},
1183+ .imageMemoryBarrierCount = 1 ,
1184+ .pImageMemoryBarriers = &barrier
1185+ };
1186+ commandBuffers[currentFrame].pipelineBarrier2 (dependency_info);
1187+ }
1188+
11031189 void createSyncObjects () {
11041190 presentCompleteSemaphore.clear ();
11051191 renderFinishedSemaphore.clear ();
0 commit comments