vulkan 中 VkRenderPass 的 使用

本文深入探讨了Vulkan渲染通道的创建与使用,包括VkRenderPassCreateInfo结构体的详细解析,以及渲染通道在framebuffer、管线创建和命令缓冲写入过程中的作用。

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. 依赖数量,指针。
他们的相关描述
使用通道的地方 主要有三处

  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;
  1. 创建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;
  1. 开始写入 命令缓冲 时,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 重新绑定。

### ### Vulkan API 正常使用流程和步骤 Vulkan 是一种低开销、跨平台的图形和计算 API,允许开发者对 GPU 进行细粒度控制。其使用流程涉及个关键步骤,从初始化到最终资源释放,每一步都需要明确配置和管理。 在使用 Vulkan 时,首先需要加载 Vulkan 库并获取所需的函数指针。随后,需要创建一个 `VkInstance`,它是整个 Vulkan 应用程序的入口点,用于初始化上下文并指定所需的扩展和验证层。验证层可用于调试和错误检查,而扩展则提供了额外的功能支持[^1]。 创建实例后,需要选择合适的物理设备(GPU),并查询其支持的功能和队列族。接着,创建逻辑设备(`VkDevice`),它与物理设备绑定,并指定需要启用的队列和功能。每个队列族支持一种操作类型,例如图形、计算或传输,应用程序需要从中获取队列用于提交命令。 为了进行渲染,必须创建与平台窗口相关的表面(`VkSurfaceKHR`),这是 Vulkan 与原生窗口系统交互的关键对象。随后,创建交换链(`VkSwapchainKHR`),它管理一组可以在屏幕上显示的图像。交换链的创建依赖于表面,并需要指定图像格式、呈现模式等参数[^2]。 接下来,创建图像视图(`VkImageView`)和帧缓冲区(`VkFramebuffer`),以便访问交换链中的图像并进行渲染。同时,还需要创建渲染通道(`VkRenderPass`),它定义了渲染过程中使用的颜色、深度和模板缓冲区的格式和操作方式[^3]。 为了执行实际的绘制或计算任务,需要构建命令缓冲区(`VkCommandBuffer`)。命令缓冲区记录了所有要执行的 GPU 命令,例如绑定管线、设置视口、绘制图元等。记录完成后,将命令缓冲区提交到相应的队列中执行。 最后,在每一帧渲染完成后,应用程序需要获取交换链中的下一个图像,提交命令缓冲区,并等待其完成,然后将图像呈现到屏幕上。整个流程需要循环执行,直到应用程序退出。在程序结束时,应正确释放所有创建的 Vulkan 对象和资源,以避免内存泄漏。 以下是一个简化版的 Vulkan 初始化和渲染流程示例代码: ```cpp VkInstance instance; VkDevice device; VkSurfaceKHR surface; VkSwapchainKHR swapchain; VkRenderPass renderPass; VkFramebuffer framebuffer; VkCommandBuffer commandBuffer; // 初始化 Vulkan 实例 createInstance(&instance); // 创建与窗口关联的表面 createSurface(instance, &surface); // 选择物理设备并创建逻辑设备 createDevice(surface, &device); // 创建交换链 createSwapchain(device, surface, &swapchain); // 创建图像视图和帧缓冲区 createFramebuffers(device, swapchain, &framebuffer); // 创建渲染通道 createRenderPass(device, &renderPass); // 记录命令缓冲区 recordCommandBuffer(commandBuffer, framebuffer, renderPass); // 提交命令并呈现图像 submitCommandBuffer(commandBuffer, device); ``` 在整个使用过程中,开发者需要负责管理所有资源的生命周期,并确保同步机制(如信号量和围栏)的正确使用,以避免竞态条件和资源冲突。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值