I draw the scene first, and then the UI using imgui, for this purpose I use 2 subpasses and 2 attachment descriptions, this suits me and works well.
//Create render color attachment
//Attachment description
VkAttachmentDescription sceneRenderColorAttachment{};
sceneRenderColorAttachment.format = swapchainImageFormat;
sceneRenderColorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
//Clear attachment before render
sceneRenderColorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
//The rendered attachment will be stored in memory for imgui render
sceneRenderColorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
//We are not interested in the stencil data
sceneRenderColorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
sceneRenderColorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
//We are not interested in the layout before starting the render
sceneRenderColorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
//The layout should be VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL because the image will be drawn on top of this ImGui and only then displayed.
sceneRenderColorAttachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
//Create imgui color attachment
//Attachment description
VkAttachmentDescription imguiColorAttachment{};
imguiColorAttachment.format = swapchainImageFormat;
imguiColorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
//Load render attachment before render imgui
imguiColorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
//Render attachment will be stored in memory for visualization
imguiColorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
//We are not interested in the stencil data
imguiColorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
imguiColorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
imguiColorAttachment.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
//We want the image to be ready for presentation using the swap chain after rendering
imguiColorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
std::vector<VkAttachmentDescription> attachmentsDescriptions = { sceneRenderColorAttachment, imguiColorAttachment };
//Subpasses and attachment references
//Subpass refers to the attachment using VkAttachmentReference
VkAttachmentReference sceneRenderColorAttachmentRef{};
//Index of the attachment that we created above earlier
sceneRenderColorAttachmentRef.attachment = 0;
sceneRenderColorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkAttachmentReference imguiColorAttachmentRef{};
imguiColorAttachmentRef.attachment = 1;
imguiColorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkSubpassDescription sceneRenderSubpass{};
sceneRenderSubpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
sceneRenderSubpass.colorAttachmentCount = 1;
sceneRenderSubpass.pColorAttachments = &sceneRenderColorAttachmentRef;
VkSubpassDescription imguiSubpass{};
imguiSubpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
imguiSubpass.colorAttachmentCount = 1;
imguiSubpass.pColorAttachments = &imguiColorAttachmentRef;
std::vector<VkSubpassDescription> subpasses = { sceneRenderSubpass, imguiSubpass };
//Subpass dependencies
VkSubpassDependency sceneRenderSubpassDependency{};
sceneRenderSubpassDependency.srcSubpass = VK_SUBPASS_EXTERNAL;
sceneRenderSubpassDependency.dstSubpass = 0;
sceneRenderSubpassDependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
sceneRenderSubpassDependency.srcAccessMask = 0;
sceneRenderSubpassDependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
sceneRenderSubpassDependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
VkSubpassDependency imguiSubpassDependency{};
imguiSubpassDependency.srcSubpass = 0;
imguiSubpassDependency.dstSubpass = 1;
imguiSubpassDependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
imguiSubpassDependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
imguiSubpassDependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
imguiSubpassDependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
std::vector<VkSubpassDependency> subpassesDependencies = { sceneRenderSubpassDependency, imguiSubpassDependency };
VkRenderPassCreateInfo renderPassInfo{};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassInfo.attachmentCount = attachmentsDescriptions.size();
renderPassInfo.pAttachments = attachmentsDescriptions.data();
renderPassInfo.subpassCount = subpasses.size();
renderPassInfo.pSubpasses = subpasses.data();
renderPassInfo.dependencyCount = subpassesDependencies.size();
renderPassInfo.pDependencies = subpassesDependencies.data();
if (vkCreateRenderPass(logicalDevice, &renderPassInfo, nullptr, &renderPass) != VK_SUCCESS) {
throw MakeErrorInfo("Failed to create renderpass!");
}
I create framebuffers like this:
problem here
---> std::vector<VkImageView> framebufferAttachments = { swapchainImageViews[i], swapchainImageViews[i] };
VkFramebufferCreateInfo framebufferInfo{};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferInfo.renderPass = renderPass;
framebufferInfo.attachmentCount = framebufferAttachments.size();
framebufferInfo.pAttachments = framebufferAttachments.data();
framebufferInfo.width = swapchainExtent.width;
framebufferInfo.height = swapchainExtent.height;
framebufferInfo.layers = 1;
if (vkCreateFramebuffer(logicalDevice, &framebufferInfo, nullptr, &swapchainFramebuffers[i]) != VK_SUCCESS) {
throw MakeErrorInfo("Failed to create framebuffer!");
}
I have to specify one attachment 2 times and I don’t like it.
Can I make my 2 attachments description refer to this one attachment so that I don’t have to specify it 2 times?