Once the Render Pass is created, it is used to create the framebuffer. Ideally, for each swapchain color image, we need a framebuffer associated with it. For example, if we have a double buffer swapchain image, then we need two framebuffers: one for the front buffer and another for the back buffer image.
The framebuffer in Vulkan is created using the vkCreateFrameBuffer()
API. Like with other Vulkan APIs, this also has a create info control structure called VkFrameBufferCreateInfo
. Refer to the following for more information on its syntax and usage:
VkResult vkCreateFrameBuffer( VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFramebuffer* pFrameBuffer);
The following table describes the various fields of the vkCreateFrameBuffer()
API:
Parameters |
Description |
|
This is the logical device handle to which the framebuffer is associated. |
|
This is the pointer to the |
|
This controls the host memory deallocation process. Refer to the Host memory section in Chapter 5, Command Buffer and Memory Management in Vulkan. |
|
This creates the |
The VkFrameBufferCreateInfo
control structure is described in the following syntax:
typedef struct VkFramebufferCreateInfo { VkStructureType type; const void* pNext; VkFramebufferCreateFlags flags; VkRenderPass renderPass; uint32_t attachmentCount; const VkImageView* pAttachments; uint32_t width; uint32_t height; uint32_t layers; } VkFramebufferCreateInfo;
The following table describes the various fields of this structure:
Parameters |
Description |
|
This refers to the type of this structure, which must be |
|
This is either |
|
This must be 0; it is reserved for future use. |
|
This is the |
|
This refers to the number of attachments associated with the framebuffer. |
|
This is an array of |
|
This refers to the width of the framebuffer in pixels. |
|
This refers to the height of the framebuffer in pixels. |
|
This refers to the layers in the framebuffer. |
The implementation of a framebuffer is simple; follow these steps:
VulkanRenderer
class. The cmdFrameBuffer
declares the command buffer responsible for creating the framebuffer (frameBuffer
):class VulkanRenderer { public: // Member functions void createFrameBuffer(bool includeDepth,bool clear= true); void destroyFrameBuffer (); // Number of frame buffer corresponding to each swap chain std::vector<VkFramebuffer> framebuffers; }
createFrameBuffer()
function:void VulkanRenderer::initialize() { const bool includeDepth = true; createFrameBuffer(includeDepth); }
vkCreateFrameBuffer()
API. This API intakes VkFrameBufferCreateInfo
in which we specify the depth and color image views as an attachment. Also, pass the created Render Pass object along with the dimensions of the framebuffer in this structure:void VulkanRenderer::createFrameBuffer(bool includeDepth) { // Dependency on createDepthBuffer(), createRenderPass() // and recordSwapChain() VkResult result; VkImageView attachments[2]; attachments[1] = Depth.view; VkFramebufferCreateInfo fbInfo = {}; fbInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; fbInfo.pNext = NULL; fbInfo.renderPass = renderPass; fbInfo.attachmentCount = includeDepth ? 2 : 1; fbInfo.pAttachments = attachments; fbInfo.width = width; fbInfo.height = height; fbInfo.layers = 1; uint32_t i; framebuffers.clear(); framebuffers.resize(swapChainObj->scPublicVars. swapchainImageCount); for (i = 0; i < swapChainObj->scPublicVars .swapchainImageCount; i++) { attachments[0] = swapChainObj->scPublicVars. colorBuffer[i].view; result = vkCreateFramebuffer(deviceObj->device, &fbInfo, NULL, &framebuffers.at(i)); assert(result == VK_SUCCESS); } }
vkDestroyFrameBuffer()
API:void VulkanApplication::deInitialize() { rendererObj->destroyRenderpass(); . . . . } void VulkanRenderer::destroyFramebuffers() { for (uint32_t i = 0; i < swapChainObj ->scPublicVars.swapchainImageCount; i++) { vkDestroyFramebuffer(deviceObj->device, framebuffers.at(i), NULL); } framebuffers.clear(); }
18.188.218.226