Use only one intermediate image

This commit is contained in:
Sascha Willems 2025-02-16 18:27:23 +01:00
parent 1cd72f3d07
commit e4cf8a6116

View file

@ -34,13 +34,13 @@ public:
VkDescriptorSetLayout descriptorSetLayout{ VK_NULL_HANDLE }; VkDescriptorSetLayout descriptorSetLayout{ VK_NULL_HANDLE };
// Intermediate images used for multi sampling // Intermediate images used for multi sampling
struct RenderImage { struct Image {
VkImage image{ VK_NULL_HANDLE }; VkImage image{ VK_NULL_HANDLE };
VkImageView view{ VK_NULL_HANDLE }; VkImageView view{ VK_NULL_HANDLE };
VkDeviceMemory memory{ VK_NULL_HANDLE }; VkDeviceMemory memory{ VK_NULL_HANDLE };
}; };
std::vector<RenderImage> renderImages; Image renderImage;
RenderImage depthStencilRenderImage; Image depthStencilRenderImage;
VulkanExample() : VulkanExampleBase() VulkanExample() : VulkanExampleBase()
{ {
@ -74,11 +74,9 @@ public:
vkDestroyPipelineLayout(device, pipelineLayout, nullptr); vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
uniformBuffer.destroy(); uniformBuffer.destroy();
for (auto i = 0; i < renderImages.size(); i++) { vkDestroyImage(device, renderImage.image, nullptr);
vkDestroyImage(device, renderImages[i].image, nullptr); vkDestroyImageView(device, renderImage.view, nullptr);
vkDestroyImageView(device, renderImages[i].view, nullptr); vkFreeMemory(device, renderImage.memory, nullptr);
vkFreeMemory(device, renderImages[i].memory, nullptr);
}
} }
} }
@ -92,37 +90,34 @@ public:
{ {
// With VK_KHR_dynamic_rendering we no longer need a frame buffer, so we can so skip the sample base framebuffer setup // With VK_KHR_dynamic_rendering we no longer need a frame buffer, so we can so skip the sample base framebuffer setup
// For multi sampling we need intermediate images that are then resolved to the final presentation image // For multi sampling we need intermediate images that are then resolved to the final presentation image
renderImages.resize(swapChain.images.size()); vkDestroyImage(device, renderImage.image, nullptr);
for (auto i = 0; i < renderImages.size(); i++) { vkDestroyImageView(device, renderImage.view, nullptr);
vkDestroyImage(device, renderImages[i].image, nullptr); vkFreeMemory(device, renderImage.memory, nullptr);
vkDestroyImageView(device, renderImages[i].view, nullptr); VkImageCreateInfo renderImageCI = vks::initializers::imageCreateInfo();
vkFreeMemory(device, renderImages[i].memory, nullptr); renderImageCI.imageType = VK_IMAGE_TYPE_2D;
VkImageCreateInfo renderImageCI = vks::initializers::imageCreateInfo(); renderImageCI.format = swapChain.colorFormat;
renderImageCI.imageType = VK_IMAGE_TYPE_2D; renderImageCI.extent = { width, height, 1 };
renderImageCI.format = swapChain.colorFormat; renderImageCI.mipLevels = 1;
renderImageCI.extent = { width, height, 1 }; renderImageCI.arrayLayers = 1;
renderImageCI.mipLevels = 1; renderImageCI.samples = multiSampleCount;
renderImageCI.arrayLayers = 1; renderImageCI.tiling = VK_IMAGE_TILING_OPTIMAL;
renderImageCI.samples = multiSampleCount; renderImageCI.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
renderImageCI.tiling = VK_IMAGE_TILING_OPTIMAL; renderImageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
renderImageCI.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; VK_CHECK_RESULT(vkCreateImage(device, &renderImageCI, nullptr, &renderImage.image));
renderImageCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; VkMemoryRequirements memReqs{};
VK_CHECK_RESULT(vkCreateImage(device, &renderImageCI, nullptr, &renderImages[i].image)); vkGetImageMemoryRequirements(device, renderImage.image, &memReqs);
VkMemoryRequirements memReqs{}; VkMemoryAllocateInfo memAllloc{};
vkGetImageMemoryRequirements(device, renderImages[i].image, &memReqs); memAllloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
VkMemoryAllocateInfo memAllloc{}; memAllloc.allocationSize = memReqs.size;
memAllloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; memAllloc.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
memAllloc.allocationSize = memReqs.size; VK_CHECK_RESULT(vkAllocateMemory(device, &memAllloc, nullptr, &renderImage.memory));
memAllloc.memoryTypeIndex = vulkanDevice->getMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); VK_CHECK_RESULT(vkBindImageMemory(device, renderImage.image, renderImage.memory, 0));
VK_CHECK_RESULT(vkAllocateMemory(device, &memAllloc, nullptr, &renderImages[i].memory)); VkImageViewCreateInfo imageViewCI = vks::initializers::imageViewCreateInfo();
VK_CHECK_RESULT(vkBindImageMemory(device, renderImages[i].image, renderImages[i].memory, 0)); imageViewCI.viewType = VK_IMAGE_VIEW_TYPE_2D;
VkImageViewCreateInfo imageViewCI = vks::initializers::imageViewCreateInfo(); imageViewCI.image = renderImage.image;
imageViewCI.viewType = VK_IMAGE_VIEW_TYPE_2D; imageViewCI.format = swapChain.colorFormat;
imageViewCI.image = renderImages[i].image; imageViewCI.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
imageViewCI.format = swapChain.colorFormat; VK_CHECK_RESULT(vkCreateImageView(device, &imageViewCI, nullptr, &renderImage.view));
imageViewCI.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
VK_CHECK_RESULT(vkCreateImageView(device, &imageViewCI, nullptr, &renderImages[i].view));
}
} }
// We need to override the default depth/stencil setup to create a depth image that supports multi sampling // We need to override the default depth/stencil setup to create a depth image that supports multi sampling
@ -191,7 +186,7 @@ public:
// This set of barriers prepares the color and depth images for output // This set of barriers prepares the color and depth images for output
vks::tools::insertImageMemoryBarrier( vks::tools::insertImageMemoryBarrier(
drawCmdBuffers[i], drawCmdBuffers[i],
renderImages[i].image, renderImage.image,
0, 0,
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_UNDEFINED,
@ -218,7 +213,7 @@ public:
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
colorAttachment.clearValue.color = { 0.0f,0.0f,0.0f,0.0f }; colorAttachment.clearValue.color = { 0.0f,0.0f,0.0f,0.0f };
// When multi sampling is used, we use intermediate images to render and resolve to the swap chain images // When multi sampling is used, we use intermediate images to render and resolve to the swap chain images
colorAttachment.imageView = renderImages[i].view; colorAttachment.imageView = renderImage.view;
colorAttachment.resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; colorAttachment.resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT;
colorAttachment.resolveImageView = swapChain.imageViews[i]; colorAttachment.resolveImageView = swapChain.imageViews[i];
colorAttachment.resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL; colorAttachment.resolveImageLayout = VK_IMAGE_LAYOUT_GENERAL;