Created
June 8, 2019 09:13
-
-
Save tristan/a479dedccabd82d8459bd8dc21e8a745 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -u /home/tristan/projects/home/vulkan-tutorial/28_mipmapping.cpp /home/tristan/projects/home/vulkan-tutorial/29_multisampling.cpp | |
--- /home/tristan/projects/home/vulkan-tutorial/28_mipmapping.cpp 2019-06-07 17:09:04.120005112 +0200 | |
+++ /home/tristan/projects/home/vulkan-tutorial/29_multisampling.cpp 2019-06-07 17:09:18.606672434 +0200 | |
@@ -151,6 +151,7 @@ | |
VkSurfaceKHR surface; | |
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE; | |
+ VkSampleCountFlagBits msaaSamples = VK_SAMPLE_COUNT_1_BIT; | |
VkDevice device; | |
VkQueue graphicsQueue; | |
@@ -170,6 +171,10 @@ | |
VkCommandPool commandPool; | |
+ VkImage colorImage; | |
+ VkDeviceMemory colorImageMemory; | |
+ VkImageView colorImageView; | |
+ | |
VkImage depthImage; | |
VkDeviceMemory depthImageMemory; | |
VkImageView depthImageView; | |
@@ -229,6 +234,7 @@ | |
createDescriptorSetLayout(); | |
createGraphicsPipeline(); | |
createCommandPool(); | |
+ createColorResources(); | |
createDepthResources(); | |
createFramebuffers(); | |
createTextureImage(); | |
@@ -258,6 +264,10 @@ | |
vkDestroyImage(device, depthImage, nullptr); | |
vkFreeMemory(device, depthImageMemory, nullptr); | |
+ vkDestroyImageView(device, colorImageView, nullptr); | |
+ vkDestroyImage(device, colorImage, nullptr); | |
+ vkFreeMemory(device, colorImageMemory, nullptr); | |
+ | |
for (auto framebuffer : swapChainFramebuffers) { | |
vkDestroyFramebuffer(device, framebuffer, nullptr); | |
} | |
@@ -336,6 +346,7 @@ | |
createImageViews(); | |
createRenderPass(); | |
createGraphicsPipeline(); | |
+ createColorResources(); | |
createDepthResources(); | |
createFramebuffers(); | |
createUniformBuffers(); | |
@@ -422,6 +433,7 @@ | |
for (const auto& device : devices) { | |
if (isDeviceSuitable(device)) { | |
physicalDevice = device; | |
+ msaaSamples = getMaxUsableSampleCount(); | |
break; | |
} | |
} | |
@@ -538,17 +550,17 @@ | |
void createRenderPass() { | |
VkAttachmentDescription colorAttachment = {}; | |
colorAttachment.format = swapChainImageFormat; | |
- colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT; | |
+ colorAttachment.samples = msaaSamples; | |
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; | |
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; | |
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; | |
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; | |
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; | |
- colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; | |
+ colorAttachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; | |
VkAttachmentDescription depthAttachment = {}; | |
depthAttachment.format = findDepthFormat(); | |
- depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT; | |
+ depthAttachment.samples = msaaSamples; | |
depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; | |
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; | |
depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; | |
@@ -556,6 +568,16 @@ | |
depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; | |
depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; | |
+ VkAttachmentDescription colorAttachmentResolve = {}; | |
+ colorAttachmentResolve.format = swapChainImageFormat; | |
+ colorAttachmentResolve.samples = VK_SAMPLE_COUNT_1_BIT; | |
+ colorAttachmentResolve.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; | |
+ colorAttachmentResolve.storeOp = VK_ATTACHMENT_STORE_OP_STORE; | |
+ colorAttachmentResolve.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; | |
+ colorAttachmentResolve.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; | |
+ colorAttachmentResolve.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; | |
+ colorAttachmentResolve.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; | |
+ | |
VkAttachmentReference colorAttachmentRef = {}; | |
colorAttachmentRef.attachment = 0; | |
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; | |
@@ -564,11 +586,16 @@ | |
depthAttachmentRef.attachment = 1; | |
depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; | |
+ VkAttachmentReference colorAttachmentResolveRef = {}; | |
+ colorAttachmentResolveRef.attachment = 2; | |
+ colorAttachmentResolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; | |
+ | |
VkSubpassDescription subpass = {}; | |
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; | |
subpass.colorAttachmentCount = 1; | |
subpass.pColorAttachments = &colorAttachmentRef; | |
subpass.pDepthStencilAttachment = &depthAttachmentRef; | |
+ subpass.pResolveAttachments = &colorAttachmentResolveRef; | |
VkSubpassDependency dependency = {}; | |
dependency.srcSubpass = VK_SUBPASS_EXTERNAL; | |
@@ -578,7 +605,7 @@ | |
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; | |
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; | |
- std::array<VkAttachmentDescription, 2> attachments = {colorAttachment, depthAttachment}; | |
+ std::array<VkAttachmentDescription, 3> attachments = {colorAttachment, depthAttachment, colorAttachmentResolve }; | |
VkRenderPassCreateInfo renderPassInfo = {}; | |
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; | |
renderPassInfo.attachmentCount = static_cast<uint32_t>(attachments.size()); | |
@@ -688,7 +715,7 @@ | |
VkPipelineMultisampleStateCreateInfo multisampling = {}; | |
multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; | |
multisampling.sampleShadingEnable = VK_FALSE; | |
- multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; | |
+ multisampling.rasterizationSamples = msaaSamples; | |
VkPipelineDepthStencilStateCreateInfo depthStencil = {}; | |
depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; | |
@@ -750,9 +777,10 @@ | |
swapChainFramebuffers.resize(swapChainImageViews.size()); | |
for (size_t i = 0; i < swapChainImageViews.size(); i++) { | |
- std::array<VkImageView, 2> attachments = { | |
- swapChainImageViews[i], | |
- depthImageView | |
+ std::array<VkImageView, 3> attachments = { | |
+ colorImageView, | |
+ depthImageView, | |
+ swapChainImageViews[i] | |
}; | |
VkFramebufferCreateInfo framebufferInfo = {}; | |
@@ -782,10 +810,19 @@ | |
} | |
} | |
+ void createColorResources() { | |
+ VkFormat colorFormat = swapChainImageFormat; | |
+ | |
+ 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); | |
+ colorImageView = createImageView(colorImage, colorFormat, VK_IMAGE_ASPECT_COLOR_BIT, 1); | |
+ | |
+ transitionImageLayout(colorImage, colorFormat, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 1); | |
+ } | |
+ | |
void createDepthResources() { | |
VkFormat depthFormat = findDepthFormat(); | |
- 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); | |
+ 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, depthImage, depthImageMemory); | |
depthImageView = createImageView(depthImage, depthFormat, VK_IMAGE_ASPECT_DEPTH_BIT, 1); | |
transitionImageLayout(depthImage, depthFormat, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1); | |
@@ -839,7 +876,7 @@ | |
stbi_image_free(pixels); | |
- 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); | |
+ 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); | |
transitionImageLayout(textureImage, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, mipLevels); | |
copyBufferToImage(stagingBuffer, textureImage, static_cast<uint32_t>(texWidth), static_cast<uint32_t>(texHeight)); | |
@@ -938,6 +975,21 @@ | |
endSingleTimeCommands(commandBuffer); | |
} | |
+VkSampleCountFlagBits getMaxUsableSampleCount() { | |
+ VkPhysicalDeviceProperties physicalDeviceProperties; | |
+ vkGetPhysicalDeviceProperties(physicalDevice, &physicalDeviceProperties); | |
+ | |
+ VkSampleCountFlags counts = std::min(physicalDeviceProperties.limits.framebufferColorSampleCounts, physicalDeviceProperties.limits.framebufferDepthSampleCounts); | |
+ if (counts & VK_SAMPLE_COUNT_64_BIT) { return VK_SAMPLE_COUNT_64_BIT; } | |
+ if (counts & VK_SAMPLE_COUNT_32_BIT) { return VK_SAMPLE_COUNT_32_BIT; } | |
+ if (counts & VK_SAMPLE_COUNT_16_BIT) { return VK_SAMPLE_COUNT_16_BIT; } | |
+ if (counts & VK_SAMPLE_COUNT_8_BIT) { return VK_SAMPLE_COUNT_8_BIT; } | |
+ if (counts & VK_SAMPLE_COUNT_4_BIT) { return VK_SAMPLE_COUNT_4_BIT; } | |
+ if (counts & VK_SAMPLE_COUNT_2_BIT) { return VK_SAMPLE_COUNT_2_BIT; } | |
+ | |
+ return VK_SAMPLE_COUNT_1_BIT; | |
+} | |
+ | |
void createTextureImageView() { | |
textureImageView = createImageView(textureImage, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT, mipLevels); | |
} | |
@@ -986,7 +1038,7 @@ | |
return imageView; | |
} | |
- void createImage(uint32_t width, uint32_t height, uint32_t mipLevels, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage& image, VkDeviceMemory& imageMemory) { | |
+ 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) { | |
VkImageCreateInfo imageInfo = {}; | |
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; | |
imageInfo.imageType = VK_IMAGE_TYPE_2D; | |
@@ -999,7 +1051,7 @@ | |
imageInfo.tiling = tiling; | |
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; | |
imageInfo.usage = usage; | |
- imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; | |
+ imageInfo.samples = numSamples; | |
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; | |
if (vkCreateImage(device, &imageInfo, nullptr, &image) != VK_SUCCESS) { | |
@@ -1068,7 +1120,14 @@ | |
sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; | |
destinationStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; | |
- } else { | |
+ } | |
+ else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { | |
+ barrier.srcAccessMask = 0; | |
+ barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; | |
+ sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; | |
+ destinationStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; | |
+ } | |
+ else { | |
throw std::invalid_argument("unsupported layout transition!"); | |
} | |
Diff finished. Fri Jun 7 17:09:46 2019 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment