vulkan 中 VkRenderPass 的 使用

vulkan 中 渲染通道创建相对独立 ,不依赖其他的渲染组件。

typedef struct VkRenderPassCreateInfo {
    VkStructureType                   sType;
    const void*                       pNext;
    VkRenderPassCreateFlags           flags;
    uint32_t                          attachmentCount;
    const VkAttachmentDescription*    pAttachments;
    uint32_t                          subpassCount;
    const VkSubpassDescription*       pSubpasses;
    uint32_t                          dependencyCount;
    const VkSubpassDependency*        pDependencies;
} VkRenderPassCreateInfo;

主要有
1. 关联附件的数量,描述指针
2. 子通道数量,描述指针
3. 依赖数量,指针。

他们的相关描述

Render Pass

是一个过程的集合,这个集合包含一组描述frame buffer的一组特征,例如 format, sample count之类的。

attachment: 用来描述frame buffer特征的,它描述了一组subpass的数据结构及之间的依赖关系,was used by subpass. 在创建Render Pass的数据结构中包含attachment的信息,以及为这个render pass需要创建的attachments的个数。

subpass;描述着色的一个阶段用来读写attachment 的一个子集,subpass从某个attachment读取出来,写入到另外的如color、depth/stencil attachment中,所以描述苏北Pass的数据结构中包含attachment的信息,如果attachment的个数为零,说明surpass没有使用 color、depth/stencil attachment, 而是使用了 image stores/atomics来产生一个输出,在这种情况下,subpass使用 frame buffer中的信息来定义着色区域,从pipeline中获取光栅化samples的相关信息。

需要注意的是不同的 subpass之间有相互依赖关系,surpass dependency 的定义类似于 pipeline barriers。在创建Render Pass的数据结构中包含surbpass的信息,以及为这个render pass需要创建的surpass的个数,,还有subpass之间的依赖关系信息。

Renderpass 》 subpass

Frame buffer > attachments

frame buffer和graphics pipeline的创建均基于 renderpass 对象,而且framebuffer必须和renderpass配合在一起使用,在创建一个framebuffer时,创建framebuffer的数据结构中就包含render pass, 这个render pass就是需要和frame buffer配合使用的, 除此之外,还包括 renderpass过程中所用到的attachments.

Render pass commands: 大致的流程为:
开始一个render pass实例来为其记录每次做subpass所需要的命令,调用函数 vkCmdBeginRenderPass来实现。
iterating over the subpasses to record command for that subpass。啥意思。就是说一个render pass 实例中有多个 subpass, render pass实例要做的事情就是遍历所有的subpass,对每个surpass的所有命令做记录。
结束renderpass实例,在结束时,它会在最后一个subpass上做所有的multisample resolve operations.
Done!



使用通道的地方 主要有三处

1. 创建VkFramebufferCreateInfo 要指定framebuffer 属于那个通道,一个通道可以指定多个 framebuffer

typedef struct VkFramebufferCreateInfo {
    VkStructureType             sType;
    const void*                 pNext;
    VkFramebufferCreateFlags    flags;
    VkRenderPass                renderPass;
    uint32_t                    attachmentCount;
    const VkImageView*          pAttachments;
    uint32_t                    width;
    uint32_t                    height;
    uint32_t                    layers;
} VkFramebufferCreateInfo;


2. 创建VkGraphicsPipelineCreateInfo 时,同样 一个通道可以创建多个管线。

typedef struct VkGraphicsPipelineCreateInfo {
    VkStructureType                                  sType;
    const void*                                      pNext;
    VkPipelineCreateFlags                            flags;
    uint32_t                                         stageCount;
    const VkPipelineShaderStageCreateInfo*           pStages;
    const VkPipelineVertexInputStateCreateInfo*      pVertexInputState;
    const VkPipelineInputAssemblyStateCreateInfo*    pInputAssemblyState;
    const VkPipelineTessellationStateCreateInfo*     pTessellationState;
    const VkPipelineViewportStateCreateInfo*         pViewportState;
    const VkPipelineRasterizationStateCreateInfo*    pRasterizationState;
    const VkPipelineMultisampleStateCreateInfo*      pMultisampleState;
    const VkPipelineDepthStencilStateCreateInfo*     pDepthStencilState;
    const VkPipelineColorBlendStateCreateInfo*       pColorBlendState;
    const VkPipelineDynamicStateCreateInfo*          pDynamicState;
    VkPipelineLayout                                 layout;
    VkRenderPass                                     renderPass;
    uint32_t                                         subpass;
    VkPipeline                                       basePipelineHandle;
    int32_t                                          basePipelineIndex;
} VkGraphicsPipelineCreateInfo;


3. 开始写入 命令缓冲 时,renderPassBeginInfo需要在vkCmdBeginRenderPass 作为参数。

VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass(
    VkCommandBuffer                             commandBuffer,
    const VkRenderPassBeginInfo*                pRenderPassBegin,
    VkSubpassContents                           contents);
typedef struct VkRenderPassBeginInfo {
    VkStructureType        sType;
    const void*            pNext;
    VkRenderPass           renderPass;
    VkFramebuffer          framebuffer;
    VkRect2D               renderArea;
    uint32_t               clearValueCount;
    const VkClearValue*    pClearValues;
} VkRenderPassBeginInfo;


需要注意 由于 一个VkRenderPass 可以指定多个 framebuffer 和 pipeline 。所以在每次写入渲染命令时 需要重新指定当前要使用的 framebuffer 和 pipeline。 framebuffer 就写入上面的结构体里,pipeline 用 vkCmdBindPipeline 重新绑定。


版权声明:本文为CSDN博主「liuhongyi0104」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/liuhongyi0104/article/details/85965236

最新文章