@@ -150,7 +150,6 @@ class HelloTriangleApplication {
150150 VkSurfaceKHR surface;
151151
152152 VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
153- VkPhysicalDeviceProperties physicalDeviceProperties;
154153 VkSampleCountFlagBits msaaSamples = VK_SAMPLE_COUNT_1_BIT;
155154 VkDevice device;
156155
@@ -171,6 +170,14 @@ class HelloTriangleApplication {
171170
172171 VkCommandPool commandPool;
173172
173+ VkImage colorImage;
174+ VkDeviceMemory colorImageMemory;
175+ VkImageView colorImageView;
176+
177+ VkImage depthMsaaImage;
178+ VkDeviceMemory depthMsaaImageMemory;
179+ VkImageView depthMsaaImageView;
180+
174181 VkImage depthImage;
175182 VkDeviceMemory depthImageMemory;
176183 VkImageView depthImageView;
@@ -230,11 +237,12 @@ class HelloTriangleApplication {
230237 createDescriptorSetLayout ();
231238 createGraphicsPipeline ();
232239 createCommandPool ();
233- createDepthResources ();
234- createFramebuffers ();
235240 createTextureImage ();
236241 createTextureImageView ();
237242 createTextureSampler ();
243+ createColorResources ();
244+ createDepthResources ();
245+ createFramebuffers ();
238246 loadModel ();
239247 createVertexBuffer ();
240248 createIndexBuffer ();
@@ -255,6 +263,12 @@ class HelloTriangleApplication {
255263 }
256264
257265 void cleanupSwapChain () {
266+ vkDestroyImageView (device, colorImageView, nullptr );
267+ vkDestroyImage (device, colorImage, nullptr );
268+ vkFreeMemory (device, colorImageMemory, nullptr );
269+ vkDestroyImageView (device, depthMsaaImageView, nullptr );
270+ vkDestroyImage (device, depthMsaaImage, nullptr );
271+ vkFreeMemory (device, depthMsaaImageMemory, nullptr );
258272 vkDestroyImageView (device, depthImageView, nullptr );
259273 vkDestroyImage (device, depthImage, nullptr );
260274 vkFreeMemory (device, depthImageMemory, nullptr );
@@ -337,6 +351,7 @@ class HelloTriangleApplication {
337351 createImageViews ();
338352 createRenderPass ();
339353 createGraphicsPipeline ();
354+ createColorResources ();
340355 createDepthResources ();
341356 createFramebuffers ();
342357 createCommandBuffers ();
@@ -408,7 +423,6 @@ class HelloTriangleApplication {
408423 for (const auto & device : devices) {
409424 if (isDeviceSuitable (device)) {
410425 physicalDevice = device;
411- vkGetPhysicalDeviceProperties (physicalDevice, &physicalDeviceProperties);
412426 msaaSamples = getMaxUsableSampleCount ();
413427 break ;
414428 }
@@ -526,24 +540,44 @@ class HelloTriangleApplication {
526540 void createRenderPass () {
527541 VkAttachmentDescription colorAttachment = {};
528542 colorAttachment.format = swapChainImageFormat;
529- colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT ;
543+ colorAttachment.samples = msaaSamples ;
530544 colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
531545 colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
532546 colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
533547 colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
534548 colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
535- colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR ;
549+ colorAttachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ;
536550
537551 VkAttachmentDescription depthAttachment = {};
538552 depthAttachment.format = findDepthFormat ();
539- depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT ;
553+ depthAttachment.samples = msaaSamples ;
540554 depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
541555 depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
542556 depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
543557 depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
544558 depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
545559 depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
546560
561+ VkAttachmentDescription colorAttachmentResolve = {};
562+ colorAttachmentResolve.format = swapChainImageFormat;
563+ colorAttachmentResolve.samples = VK_SAMPLE_COUNT_1_BIT;
564+ colorAttachmentResolve.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
565+ colorAttachmentResolve.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
566+ colorAttachmentResolve.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
567+ colorAttachmentResolve.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
568+ colorAttachmentResolve.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
569+ colorAttachmentResolve.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
570+
571+ VkAttachmentDescription depthAttachmentResolve = {};
572+ depthAttachmentResolve.format = findDepthFormat ();
573+ depthAttachmentResolve.samples = VK_SAMPLE_COUNT_1_BIT;
574+ depthAttachmentResolve.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
575+ depthAttachmentResolve.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
576+ depthAttachmentResolve.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
577+ depthAttachmentResolve.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
578+ depthAttachmentResolve.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
579+ depthAttachmentResolve.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
580+
547581 VkAttachmentReference colorAttachmentRef = {};
548582 colorAttachmentRef.attachment = 0 ;
549583 colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
@@ -552,11 +586,16 @@ class HelloTriangleApplication {
552586 depthAttachmentRef.attachment = 1 ;
553587 depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
554588
589+ VkAttachmentReference colorAttachmentResolveRef = {};
590+ colorAttachmentResolveRef.attachment = 2 ;
591+ colorAttachmentResolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
592+
555593 VkSubpassDescription subpass = {};
556594 subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
557595 subpass.colorAttachmentCount = 1 ;
558596 subpass.pColorAttachments = &colorAttachmentRef;
559597 subpass.pDepthStencilAttachment = &depthAttachmentRef;
598+ subpass.pResolveAttachments = &colorAttachmentResolveRef;
560599
561600 VkSubpassDependency dependency = {};
562601 dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
@@ -566,7 +605,7 @@ class HelloTriangleApplication {
566605 dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
567606 dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
568607
569- std::array<VkAttachmentDescription, 2 > attachments = {colorAttachment, depthAttachment};
608+ std::array<VkAttachmentDescription, 4 > attachments = {colorAttachment, depthAttachment, colorAttachmentResolve, depthAttachmentResolve };
570609 VkRenderPassCreateInfo renderPassInfo = {};
571610 renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
572611 renderPassInfo.attachmentCount = static_cast <uint32_t >(attachments.size ());
@@ -676,7 +715,7 @@ class HelloTriangleApplication {
676715 VkPipelineMultisampleStateCreateInfo multisampling = {};
677716 multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
678717 multisampling.sampleShadingEnable = VK_FALSE;
679- multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT ;
718+ multisampling.rasterizationSamples = msaaSamples ;
680719
681720 VkPipelineDepthStencilStateCreateInfo depthStencil = {};
682721 depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
@@ -738,7 +777,9 @@ class HelloTriangleApplication {
738777 swapChainFramebuffers.resize (swapChainImageViews.size ());
739778
740779 for (size_t i = 0 ; i < swapChainImageViews.size (); i++) {
741- std::array<VkImageView, 2 > attachments = {
780+ std::array<VkImageView, 4 > attachments = {
781+ colorImageView,
782+ depthMsaaImageView,
742783 swapChainImageViews[i],
743784 depthImageView
744785 };
@@ -770,13 +811,27 @@ class HelloTriangleApplication {
770811 }
771812 }
772813
814+ void createColorResources () {
815+ VkFormat colorFormat = swapChainImageFormat;
816+
817+ createImage (swapChainExtent.width , swapChainExtent.height , 1 , msaaSamples, colorFormat, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, colorImage, colorImageMemory);
818+ colorImageView = createImageView (colorImage, colorFormat, VK_IMAGE_ASPECT_COLOR_BIT, 1 );
819+
820+ transitionImageLayout (colorImage, colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1 );
821+ }
822+
773823 void createDepthResources () {
774824 VkFormat depthFormat = findDepthFormat ();
775825
776- createImage (swapChainExtent.width , swapChainExtent.height , 1 , depthFormat, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, depthImage, depthImageMemory);
826+ createImage (swapChainExtent.width , swapChainExtent.height , 1 , VK_SAMPLE_COUNT_1_BIT, depthFormat, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, depthImage, depthImageMemory);
777827 depthImageView = createImageView (depthImage, depthFormat, VK_IMAGE_ASPECT_DEPTH_BIT, 1 );
778828
779829 transitionImageLayout (depthImage, depthFormat, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1 );
830+
831+ createImage (swapChainExtent.width , swapChainExtent.height , 1 , msaaSamples, depthFormat, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, depthMsaaImage, depthMsaaImageMemory);
832+ depthMsaaImageView = createImageView (depthMsaaImage, depthFormat, VK_IMAGE_ASPECT_DEPTH_BIT, 1 );
833+
834+ transitionImageLayout (depthMsaaImage, depthFormat, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1 );
780835 }
781836
782837 VkFormat findSupportedFormat (const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features) {
@@ -827,7 +882,7 @@ class HelloTriangleApplication {
827882
828883 stbi_image_free (pixels);
829884
830- createImage (texWidth, texHeight, mipLevels, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, textureImage, textureImageMemory);
885+ createImage (texWidth, texHeight, mipLevels, VK_SAMPLE_COUNT_1_BIT, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, textureImage, textureImageMemory);
831886
832887 transitionImageLayout (textureImage, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, mipLevels);
833888 copyBufferToImage (stagingBuffer, textureImage, static_cast <uint32_t >(texWidth), static_cast <uint32_t >(texHeight));
@@ -927,6 +982,9 @@ class HelloTriangleApplication {
927982 }
928983
929984VkSampleCountFlagBits getMaxUsableSampleCount () {
985+ VkPhysicalDeviceProperties physicalDeviceProperties;
986+ vkGetPhysicalDeviceProperties (physicalDevice, &physicalDeviceProperties);
987+
930988 VkSampleCountFlags counts = std::min (physicalDeviceProperties.limits .framebufferColorSampleCounts , physicalDeviceProperties.limits .framebufferDepthSampleCounts );
931989 if (counts & VK_SAMPLE_COUNT_64_BIT) { return VK_SAMPLE_COUNT_64_BIT; }
932990 if (counts & VK_SAMPLE_COUNT_32_BIT) { return VK_SAMPLE_COUNT_32_BIT; }
@@ -985,7 +1043,7 @@ VkSampleCountFlagBits getMaxUsableSampleCount() {
9851043 return imageView;
9861044 }
9871045
988- void createImage (uint32_t width, uint32_t height, uint32_t mipLevels, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage& image, VkDeviceMemory& imageMemory) {
1046+ void createImage (uint32_t width, uint32_t height, uint32_t mipLevels, VkSampleCountFlagBits numSamples, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage& image, VkDeviceMemory& imageMemory) {
9891047 VkImageCreateInfo imageInfo = {};
9901048 imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
9911049 imageInfo.imageType = VK_IMAGE_TYPE_2D;
@@ -998,7 +1056,7 @@ VkSampleCountFlagBits getMaxUsableSampleCount() {
9981056 imageInfo.tiling = tiling;
9991057 imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
10001058 imageInfo.usage = usage;
1001- imageInfo.samples = VK_SAMPLE_COUNT_1_BIT ;
1059+ imageInfo.samples = numSamples ;
10021060 imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
10031061
10041062 if (vkCreateImage (device, &imageInfo, nullptr , &image) != VK_SUCCESS) {
@@ -1067,7 +1125,14 @@ VkSampleCountFlagBits getMaxUsableSampleCount() {
10671125
10681126 sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
10691127 destinationStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
1070- } else {
1128+ }
1129+ else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
1130+ barrier.srcAccessMask = 0 ;
1131+ barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1132+ sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
1133+ destinationStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
1134+ }
1135+ else {
10711136 throw std::invalid_argument (" unsupported layout transition!" );
10721137 }
10731138
0 commit comments