Vulkan 学习(11)---- Vulkan RenderPass 创建

RenderPass 概述

Vulkan 渲染通道(RenderPass) 定义了整个渲染管线一次执行的过程,包括了渲染所使用的所有资源和操作的描述(比如指定渲染管线的渲染目标,告诉管线要渲染到哪里)

RenderPass 本质上是一个渲染流程的完整描述(管理渲染流程),包括如何渲染这些数据的元数据和指令,但是不包括实际的数据(图像),通过与 FrameBuffer 结合来获取实际的图像数据

Vulkan编程,RenderPass是必不可少的,它必须包含一个或者多个子通道(SubPass)

每个子通道表示一个渲染阶段,并且都是使用 RenderPass 中定义的资源描述这个阶段的渲染的步骤

RenderPass 是通过附件(Attachment)的形式描述图像资源,包括颜色附件(Color Attachment)、深度/模板附件(Depth/Stencil Attachment)、用于多重采样的的解析附件(Resolve Attachment)和输入附件(Input Attachment)等,

RenderPassFrameBuffer 的关系密切,FrameBuffer 代表了 RenderPass 使用的具体内存集合,定义了 RenderPass 中每个 ImageView 与附件的对应关系

RenderPass 使得开发者能够更精细的控制渲染过程,优化性能,同时适应现代GPU架构的特点

Vulkan tutorial:
Render passes in Vulkan describe the type of images that are used during rendering operations, how they will be used, and how their contents should be treated. In our initial triangle rendering application, we’ll tell Vulkan that we will use a single image as color target and that we want it to be cleared to a solid color right before the drawing operation.

(Render pass 主要标志如何和 image 交互,是作为颜色,深度,模板附件还是其他作用等)
Note:可以理解为 RenderPass 定义了对 vkImage的操作关系

RenderPass 创建

vkCreateRenderPass 的函数原型如下:

VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass(
    VkDevice                                    device,
    const VkRenderPassCreateInfo*               pCreateInfo,
    const VkAllocationCallbacks*                pAllocator,
    VkRenderPass*                               pRenderPass);

关键结构 VkRenderPassCreateInfo 的结构:

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;`
附件描述

附件描述(Attachement Description) 定义了在渲染过程中使用的图像资源,包括它们的格式,样本数、加载和存储操作等
比如定义一个深度附件和模板附件:

// 定义颜色附件描述
VkAttachmentDescription colorAttachment = {
   
   };
colorAttachment.format = VK_FORMAT_R8G8B8A8_UNORM; // 交换链图像格式
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT; // 采样数
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; // 在渲染前清除附件
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; // 在渲染后存储附件内容
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; // 不关心模板加载操作
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; 
### Vulkan 渲染通道概念 渲染通道(Render Pass)是 Vulkan 中的一个重要特性,用于描述图像子资源的状态转换过程以及附着点之间的依赖关系。通过这种方式,应用程序可以精确地告诉 GPU 如何处理不同阶段的数据流动和状态变化[^1]。 在创建一个 `VkRenderPass` 对象时,需要指定多个参数,包括但不限于颜色、深度/模板缓冲区等信息。这些设置决定了后续帧缓存对象如何与之关联并执行具体的绘制操作[^4]。 具体来说,在初始化过程中涉及到如下几个方面: - **附件描述符 (Attachment Descriptions)**:定义了参与此渲染流程中的所有图像视图及其属性; - **子通道 (Subpass)** :表示一组命令集,它们共享相同的输入输出配置; - **依赖项 (Dependencies)**:指定了各子通道间存在的同步条件或屏障机制。 ```cpp // 创建 VkRenderPass 的 C++ 代码片段 VkRenderPassCreateInfo renderPassInfo{}; renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; renderPassInfo.attachmentCount = static_cast<uint32_t>(attachments.size()); renderPassInfo.pAttachments = attachments.data(); renderPassInfo.subpassCount = 1; // 假设只有一个子通道 renderPassInfo.pSubpasses = &subpass; if (vkCreateRenderPass(device, &renderPassInfo, nullptr, &renderPass) != VK_SUCCESS) { throw std::runtime_error("failed to create render pass!"); } ``` 这段代码展示了如何构建一个简单的渲染通道实例,并将其绑定至逻辑设备上。这里假设只存在单一类型的附件列表及相应的子通道结构体。 当实际应用中涉及复杂的场景渲染任务时,则可能需要设计更加精细的多级嵌套式的渲染管道架构,从而充分利用现代GPU的强大功能实现高效的图形渲染效果。 #### 使用示例 为了更好地理解上述理论部分的内容,下面给出一段完整的C++代码用来展示怎样在一个窗口内呈现基本的颜色填充矩形区域: ```cpp void initFramebuffers() { swapChainFramebuffers.resize(swapChainImageViews.size()); for (size_t i = 0; i < swapChainImageViews.size(); ++i){ VkFramebufferCreateInfo framebufferInfo{}; framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; framebufferInfo.renderPass = renderPass; framebufferInfo.attachmentCount = 1; framebufferInfo.pAttachments = &swapChainImageViews[i]; framebufferInfo.width = swapChainExtent.width; framebufferInfo.height = swapChainExtent.height; framebufferInfo.layers = 1; if(vkCreateFramebuffer(device,&framebufferInfo,nullptr,&swapChainFramebuffers[i])!=VK_SUCCESS){ throw std::runtime_error("Failed to create framebuffer!"); } } } void drawFrame(){ vkWaitForFences(device,1,&inFlightFences[currentFrame],VK_TRUE,UINT64_MAX); uint32_t imageIndex; auto result = vkAcquireNextImageKHR( device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex); ... VkSubmitInfo submitInfo{}; ... vkQueueSubmit(graphicsQueue,1,&submitInfo,fence); vkQueuePresentKHR(presentQueue,&presentInfo); } ``` 以上函数分别实现了交换链帧缓存器(`VkFramebuffer`) 和绘图帧 (`drawFrame`) 的准备工作。前者负责连接特定于平台表面的具体像素数据源到之前所建立好的渲染通道路由之中去;后者则包含了提交给队列的一系列指令集合,最终完成整个画面显示的过程。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值