Vulkan【15】图形管线(Graphics Pipline)

2023-11-14

创建图形管线

本节的代码是 14-init_pipeline.cpp

你越来越接近把这些拉到一起来渲染一个立方体!下一步是通过设置图形管道来配置GPU来进行渲染。

一个图形管线由着色阶段、管线布局、渲染过程和固定功能管线阶段组成。您在前面的部分中定义了着色阶段和管线布局。在这里,您将配置其余的固定功能管线阶段。这包括填充一些用于创建管线的“create info”数据结构。在这里执行的大部分工作都配置了逐片段操作,就在这些片段被放置到framebuffer之前。

如下图:

Graphics Pipeline

下一步是配置管线状态对象,由右下方的灰色方框表示。最后一步是将指向左上角的紫色管线框连接起来,以完成图形管线的定义。

动态状态

动态管线状态是这样的一种状态:它可以在命令缓冲区执行期间被命令改变。
在命令缓冲区执行过程中,预先通知哪些状态是动态的,这对于驱动程序来说是很有用的,因为它设置了用于命令缓冲区执行的GPU。

样例提供了它打算在命令缓冲区执行期间更改的状态列表。在这里,代码首先创建一个动态状态列表,并在它们开始时全部禁用。

VkDynamicState dynamicStateEnables[VK_DYNAMIC_STATE_RANGE_SIZE];
VkPipelineDynamicStateCreateInfo dynamicState = {};
memset(dynamicStateEnables, 0, sizeof dynamicStateEnables);
dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
dynamicState.pNext = NULL;
dynamicState.pDynamicStates = dynamicStateEnables;
dynamicState.dynamicStateCount = 0;

稍后,示例表明它将通过一个命令缓冲区命令动态地改变一些状态,所以在配置viewport 和scissors时,它将改变dynamicStateEnables数组。
为了清晰起见,修改dynamicStateEnables的代码会始终保持在viewport 和 scissors配置之后。

管线顶点输入状态

当你创建顶点缓冲时,你已经初始化了顶点输入状态,因为在那个时候它很简单。输入状态包括顶点数据的格式和排列。您可以查看“顶点缓冲区”示例,看看如何设置vi_bindingvi_binding 变量。

VkPipelineVertexInputStateCreateInfo vi;
vi.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vi.pNext = NULL;
vi.flags = 0;
vi.vertexBindingDescriptionCount = 1;
vi.pVertexBindingDescriptions = &info.vi_binding;
vi.vertexAttributeDescriptionCount = 2;
vi.pVertexAttributeDescriptions = info.vi_attribs;

管线顶点输入装配状态

输入装配状态基本上表明了你希望你的顶点画成什么样的几何。比如点、线、三角条带或者三角扇形。在这里,我们只使用三角形列表,每三个顶点构成一个三角形:

VkPipelineInputAssemblyStateCreateInfo ia;
ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
ia.pNext = NULL;
ia.flags = 0;
ia.primitiveRestartEnable = VK_FALSE;
ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;

管线光栅化状态

下一个数据结构在GPU中配置光栅化操作。

VkPipelineRasterizationStateCreateInfo rs;
rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
rs.pNext = NULL;
rs.flags = 0;
rs.polygonMode = VK_POLYGON_MODE_FILL;
rs.cullMode = VK_CULL_MODE_BACK_BIT;
rs.frontFace = VK_FRONT_FACE_CLOCKWISE;
rs.depthClampEnable = VK_TRUE;
rs.rasterizerDiscardEnable = VK_FALSE;
rs.depthBiasEnable = VK_FALSE;
rs.depthBiasConstantFactor = 0;
rs.depthBiasClamp = 0;
rs.depthBiasSlopeFactor = 0;
rs.lineWidth = 1.0f;

这些字段设置了一些相当常见的值。您可能会发现到frontFace成员与GL函数glFrontFace()之间的相关性。

管线颜色混合状态

混合是另一个“固定管道的结束”操作,您可以在这里进行配置,以简单地替换目标中的像素:

VkPipelineColorBlendStateCreateInfo cb;
cb.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
cb.pNext = NULL;
cb.flags = 0;
VkPipelineColorBlendAttachmentState att_state[1];
att_state[0].colorWriteMask = 0xf;
att_state[0].blendEnable = VK_FALSE;
att_state[0].alphaBlendOp = VK_BLEND_OP_ADD;
att_state[0].colorBlendOp = VK_BLEND_OP_ADD;
att_state[0].srcColorBlendFactor = VK_BLEND_FACTOR_ZERO;
att_state[0].dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
att_state[0].srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
att_state[0].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
cb.attachmentCount = 1;
cb.pAttachments = att_state;
cb.logicOpEnable = VK_FALSE;
cb.logicOp = VK_LOGIC_OP_NO_OP;
cb.blendConstants[0] = 1.0f;
cb.blendConstants[1] = 1.0f;
cb.blendConstants[2] = 1.0f;
cb.blendConstants[3] = 1.0f;

注意,有些配置信息是根据每个附件提供的。在您的管线中,您需要为每个颜色附件都有一个VkPipelineColorBlendAttachmentState。在这个例子里,只有一个颜色附件。

colorWriteMask表示R,G,B,A这四个部分中哪些可以被写入。此处,你允许四个都可被写入。

禁用blendEnable表明在att_state[0]中剩下的与混合相关的设置将不起作用。

您还禁用了“写像素逻辑”操作,因为在将像素写入framebuffer时,这个示例只是做了一个简单的替换。

混合常量用于一些“混合因素”(例如,VK_BLEND_FACTOR_CONSTANT_COLOR),并被设置为一些合理的东西,只是它们在本示例中没有使用。

管道视口状态

"渲染立方体"样例将使用命令缓冲区中的命令来设置viewport和scissors 矩形。这段代码告诉驱动程序,这些viewport和scissors 状态是动态的,且忽略了pViewPortspScissors 成员。

VkPipelineViewportStateCreateInfo vp = {};
vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
vp.pNext = NULL;
vp.flags = 0;
vp.viewportCount = 1;
dynamicStateEnables[dynamicState.dynamicStateCount++] = VK_DYNAMIC_STATE_VIEWPORT;
vp.scissorCount = 1;
dynamicStateEnables[dynamicState.dynamicStateCount++] = VK_DYNAMIC_STATE_SCISSOR;
vp.pScissors = NULL;
vp.pViewports = NULL;

管道深度模板状态

继续使用后端固定功能初始化,通过为常用的配置设置深度缓冲,并禁用模板操作。

VkPipelineDepthStencilStateCreateInfo ds;
ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
ds.pNext = NULL;
ds.flags = 0;
ds.depthTestEnable = VK_TRUE;
ds.depthWriteEnable = VK_TRUE;
ds.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
ds.depthBoundsTestEnable = VK_FALSE;
ds.minDepthBounds = 0;
ds.maxDepthBounds = 0;
ds.stencilTestEnable = VK_FALSE;
ds.back.failOp = VK_STENCIL_OP_KEEP;
ds.back.passOp = VK_STENCIL_OP_KEEP;
ds.back.compareOp = VK_COMPARE_OP_ALWAYS;
ds.back.compareMask = 0;
ds.back.reference = 0;
ds.back.depthFailOp = VK_STENCIL_OP_KEEP;
ds.back.writeMask = 0;
ds.front = ds.back;

因为您确实想要深度缓冲,所以您可以启用深度缓冲写入和测试。另外,您将深度缓冲比较操作设置为常用的VK_COMPARE_OP_LESS_OR_EQUAL。最后,您禁用了模板操作,因为这个示例不需要它。

管线多重采样状态

在这个例子中,你不会去做任何高昂的多重采样才做,所以通过设置无多重采样来完成管线配置。

VkPipelineMultisampleStateCreateInfo ms;
ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
ms.pNext = NULL;
ms.flags = 0;
ms.pSampleMask = NULL;
ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
ms.sampleShadingEnable = VK_FALSE;
ms.alphaToCoverageEnable = VK_FALSE;
ms.alphaToOneEnable = VK_FALSE;
ms.minSampleShading = 0.0;

把所有的东西都组合到一起——创建图形管线

最后,您拥有创建管道所需的所有信息:

VkGraphicsPipelineCreateInfo pipeline;
pipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
pipeline.pNext = NULL;
pipeline.layout = info.pipeline_layout;
pipeline.basePipelineHandle = VK_NULL_HANDLE;
pipeline.basePipelineIndex = 0;
pipeline.flags = 0;
pipeline.pVertexInputState = &vi;
pipeline.pInputAssemblyState = &ia;
pipeline.pRasterizationState = &rs;
pipeline.pColorBlendState = &cb;
pipeline.pTessellationState = NULL;
pipeline.pMultisampleState = &ms;
pipeline.pDynamicState = &dynamicState;
pipeline.pViewportState = &vp;
pipeline.pDepthStencilState = &ds;
pipeline.pStages = info.shaderStages;
pipeline.stageCount = 2;
pipeline.renderPass = info.render_pass;
pipeline.subpass = 0;

res = vkCreateGraphicsPipelines(info.device, NULL, 1,
                                &pipeline, NULL, &info.pipeline);

info.pipeline_layout, info.shaderStages, 和info.render_pass 成员已经在本教程之前的几个章节中被初始化。剩下的也在本节中被设置。

在创建管线之后,您就可以继续下一节并绘制立方体了。

© Copyright 2016 LunarG, Inc

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vulkan【15】图形管线(Graphics Pipline) 的相关文章

  • 矩阵和向量的乘法顺序

    矩阵和向量的乘法顺序 似乎经常有人被这个问题转晕 向量有两种表达形式 行向量和列向量 对应的矩阵也有行矩阵和列矩阵 采用哪种形式和左右手系无关 行矩阵 三个轴向量为前三行 最后一行为位移变换 连乘时从左到右接合 左边的变换先应用 变换向量时
  • matlab画对数坐标!

    在很多工程问题中 通过对数据进行对数转换可以更清晰地看出数据的某些特征 在对数坐标系中描绘数据点的曲线 可以直接地表现对数转换 对数转换有双对数坐标转换和单轴对数坐标转换两种 用loglog函数可以实现双对数坐标转换 用semilogx和s
  • Vulkan-程序结构

    程序结构 一般来说 完整的Vulkan程序包含 创建Vulkan实例 获取物理设备列表创建逻辑设备 创建命令缓冲 获取设备中支持图形工作的队列 初始化交换链 创建深度缓冲 创建渲染通道 创建帧缓冲 创建绘制对象 初始化渲染管线 创建栅栏和初
  • Vulkan_片元着色器特效5(泛光Bloom)

    本部分主要结合上一部分的Vulkan 片元着色器特效4 高动态范围HDR 来综合展示HDR 泛光场景 主要参照 LearnOpenGL中的Bloom章节 一 基本原理 Bloom使我们能够注意到一个明亮的物体真的有种明亮的感觉 泛光可以极大
  • 关于 Vulkan 简介 —— Android N 引入新的 3D 渲染引擎

    关于 Vulkan Vulkan 被视作是 OpenGL 的后续产品 它是一种多平台 API 可支持开发人员准备游戏 CAD 工具 性能基准测试等高性能图形应用 它可在不同的操作系统 比如 Windows Linux 或 Android 上
  • 【图形与渲染】相机平面镜反射与斜裁剪矩阵(下)-斜裁剪矩阵

    上一篇文章分析了平面镜反射效果实现中 如何计算镜像矩阵 我们已经可以得到镜像相机并渲染出镜像后的效果了 但是只是纯粹的镜像会遇到以下问题 如图 当相机镜像到C 位置后 其视锥体裁剪范围是A B 但实际应该位于反射贴图中的区域仅仅只有A区域
  • 深入探索透视投影变换(续)

    潘宏 2009 4 14 本人水平有限 疏忽错误在所难免 还请各位数学高手 编程高手不吝赐教 email popyy netease com B站专栏 https b23 tv oWsl6PD 在上一篇文章中我们讨论了透视投影变换的原理 分
  • 偶然发现的一篇相见很晚的文章:如何学好游戏编程

    今天偶然发现一篇介绍如何学好游戏编程的文章 相见恨晚呀 特转载 转帖地址 http new qzone qq com 79134054 blog 1226580538 如何学好游戏编程 此篇文章献给那些为了游戏编程不怕困难的热血青年 它的神
  • Vulkan 绘制显示设计

    背景 众所周知 Vulkan是个跨平台的图形渲染API 为了友好地支持跨平台 Vulkan自然也抽象出了很多接口层去对接各个操作系统 抹平系统间的差异 Swap Chains即为WSI 其本质上是一种图像队列 此队列会按顺序依次将队列中的若
  • 在silverlight中定制自己的MessageBox(消息框)

    在silverlight中 如果想使用 消息框 可使用下面的方法 即 HtmlPage Window Alert 消息框内容 如果想要显示更加复杂的内容或定义消息框样式的话 基本上没有什么好的方法 最近在网上看到了一篇文章 该文章的作者也谈
  • 为什么我们需要多个渲染通道和子通道?

    我过去有过使用 DirectX12 的经验 但我不记得 Vulkan 中类似渲染通道的东西 所以我无法进行类比 如果我理解正确 则同一子通道内的命令缓冲区不需要同步 那么为什么要复杂化并制作多个呢 为什么我不能只使用一个命令缓冲区并将所有与
  • 如何使 VK_LAYER_KHRONOS_validation 可用?

    解决方案 卸载 vulkan 在注册表 HKLM SOFTWARE Khronos Vulkan ExplicitLayers 和 HKLM SOFTWARE WOW6432Node Khronos Vulkan ExplicitLayer
  • Vulkan 中的 VKAPI_ATTR 和 VKAPI_CALL 宏

    我一直在寻找但我仍然不确定what VKAPI ATTR and VKAPI CALL是 我不确定它们是否应该是一个宏或一些我不知道的奇特的 C 函数声明 What is VKAPI ATTR void VKAPI CALL vkComma
  • 在 Android 中将外部缓冲区导入 Vulkan 时出现问题

    我正在尝试使用 Vulkan 在 Android 10 中显示图像 管道看起来像这样 MediaCodec gt ImageReader gt AHardwareBuffer 传递到 Vulkan 上下文 gt 映射到 Vulkan gt
  • 如果“buffer”是“coherent”,那么读取字段或执行“atomicAdd(field, 0)”之间有什么区别吗?

    这是 Vulkan 语义 如果有什么不同的话 假设如下 layout coherent buffer B uint field b 假设该字段正在被同一着色器 或派生着色器 的其他调用修改atomic 功能 如果着色器调用想要从中执行原子读
  • 有没有一种方法可以在不使用暂存缓冲区的情况下更新纹理?

    我正在与https vulkan tutorial com https vulkan tutorial com 深度缓冲代码作为基础 进行了一些更改以每帧更新命令缓冲区 我正在使用一种粗略的方法来检查 fps 不确定它到底有多准确 但我正在
  • Vulkan 验证层无法在 Linux 上加载/工作

    我有基本的 Vulkan 应用程序 Hello Triangle 源自本教程 https vulkan tutorial com 在调试模式下 我使用两个验证层 VK LAYER KHRONOS validation and VK LAYE
  • xvfb(带有 Mesa 19.2)与 Vulkan 兼容吗?

    我正在尝试在无头 Ubuntu 19 10 虚拟机上运行基于 Vulkan 的图形应用程序 通过xvfb https en wikipedia org wiki Xvfb 从裸露的 Ubuntu 19 10 映像开始 使用创建lxc htt
  • Vulkan命令执行顺序

    引用Vulkan 1 0规范文档 chapter 5 Command Buffers 第4段 除非另有说明 并且没有显式同步 否则通过命令缓冲区提交到队列的各种命令可以按相对于彼此的任意顺序执行 和 或同时执行 在第2 1 1章 队列操作
  • vulkan 扩展:哪些由谁支持?

    有EXT KHR or AMD or NV扩展 也许还有其他一些 我知道NV means NvidiaAMD 不太可能支持 it nv 扩展 但是 khr 或 ext 又如何呢 他们是所有人都强制支持的吗 有一个website https

随机推荐

  • 什么是图神经网络

    2019年可以说是图神经网络元年 01 什么是图神经网络 1 图和属性图 要了解图神经网络 首先要了解图 图是由节点和边组成的 如下图所示 一般图中的节点表示实体对象 比如一个用户 一件商品 一辆车 一张银行卡等都可以作为节点 边代表事件或
  • 服务器windows操作系统安装,服务器windows操作系统的安装.doc

    服务器windows操作系统的安装 Windows 2K3 2K8系统的安装 注 在这两个操作系统的安装中尤其要注意RAID卡驱动的加载 Windows server 2003标准版的安装 一 准备工作 Windows 2003标准版的安装
  • Unity之三:配置向导

    文章目录 一 C标准 编译器 微控制器 二 选项 2 1 整数类型 2 1 1 UNITY EXCLUDE STDINT H 2 1 2 UNITY EXCLUDE LIMITS H 2 1 3 UNITY INT WIDTH 2 1 4
  • 项目重构之起始

    百层之台始于累土 合抱之木生于毫末 转眼间来到公司已历三个寒暑 愈加光亮鬓角 隆起的肚腩 无不彰显着开发功力日渐深厚 公司的产品也从H5商城成长为了一款app 步入了他的青年阶段 也许是青春期的原因 也许是成长路上各种功能迭代导致 总而言之
  • Keil5(MDK5)在调试(debug)过程中遇到的问题

    参考原子哥教程 使用开发板 STM32F103RC Keil5 MDK5 在调试 debug 过程中崩溃 IDE已停止运行 http blog csdn net qq 33259138 article details 70224581 现象
  • Py的ipykernel:Python库介绍、安装及使用攻略

    Py的ipykernel Python库介绍 安装及使用攻略 ipykernel是一个用于在Jupyter Notebook中运行Python代码的包 它可以将Python代码转化为可以在IPython内核上运行的格式 下面我们将详细介绍如
  • C/C++中如何获取数组的长度?

    C C 中没有提供 直接获取数组长度的函数 对于存放字符串的字符数组提供了一个strlen函数获取长度 那么对于其他类型的数组如何获取他们的长度呢 其中一种方法是使 用sizeof array sizeof array 0 在C语言中习惯上
  • ctfhub技能树部分wp(潦草笔记)

    备份文件下载 vim缓存 在使用vim时会创建临时缓存文件 关闭vim时缓存文件则会被删除 当vim异常退出后 因为未处理缓存文件 导致可以通过缓存文件恢复原始文件内容 隐藏文件index php swp前加 以 index php 为例
  • 仿牛客网项目第三章:开发社区核心功能(详细步骤和思路)

    目录 1 过滤敏感词 1 1 目的 1 2 实现方法 1 3 前缀树 1 4 敏感词过滤步骤 为发帖子做准备 2 发布帖子 2 1 AJAX介绍 2 2 AJAX使用实例 3 帖子详情 3 1 实现功能 3 2 实现过程 4 事务管理 4
  • little endian && big-endian

    java 的ClassFile采用big endian存储数据 Intel x86 采用little endian Motorola采用big endian 0x1234 Intel 地址 0x4000 0000 0x34 0x4000 0
  • vue-使用sass定义全局样式及变量

    vue cli2使用sass定义全局样式及变量 vue cli2创建的vue项目使用sass预处理器需按顺序安装以下插件 其中sass loader版本和node sass需要安装固定版本 其他的依赖不要求版本 亲测有效 如果不不固定sas
  • unity Domain Reload & scene Reload 静态变量重置

    关闭 Domain Reload 选项后 c 的静态变量在下次运行时不会怎么重置 需要手动添加重置代码 使用下面的属性设置重置变量函数 using UnityEngine public class StaticCounterExampleF
  • ns.ajax,UIWebView使用NSURLProtocol(拦截),ajax加载失败的问题

    问题 ajax跨域访问是一个老问题了 解决方法很多 比较常用的是JSONP方法 JSONP方法是一种非官方方法 而且这种方法只支持GET方式 不如POST方式安全 即使使用jquery的jsonp方法 type设为POST 也会自动变为GE
  • 解决eclipse新建dynamic web project没有apache的Runtime environment问题

    在新建eclipse web项目时候 想选择Tomact服务器 不过运行时环境选择中没有 没有出现下图的Apache目录吗 网络上好像没有找到教程 其实很简单 只是没有装上相应的插件 解决步骤如下 1 打开Help gt Install N
  • ThinkPad BIOS 设置详解

    ThinkPad BIOS 设置详解 ThinkPad BIOS 设置详解 主流 新机型 在网上查看了相关资料 发现好多都是T40或者更老的BIOS设置信息 不适合现在的主流以及新机型 于是找到分享该贴 希望对各位有所帮助 简洁的分割线 T
  • Python-错误与异常处理

    通常情况下 在try语句块中写我们想要的逻辑 发生错误和异常时Python解释器会采用raise方法即将异常抛出 except语句可以承接raise方法抛出的异常并对异常做出处理 Python中有三种异常捕获与处理形式 第一种 try ex
  • 为什么MySQL字符串不加引号索引失效?《死磕MySQL系列 十一》

    群里一个小伙伴在问为什么MySQL字符串不加单引号会导致索引失效 这个问题估计很多人都知道答案 没错 是因为MySQL内部进行了隐式转换 本期文章就聊聊什么是隐式转换 为什么会发生隐式转换 文章目录 系列文章 一 几大索引失效原因 二 从规
  • 解决git中文乱码

    1 配置git bash idea 随便找地方打开git bash 右击窗口进入options 分别将text选项的Locale改为zh CN character set改为UTF 8 如图所示 2 命令执行 我改了这个就好了 如果不行 在
  • C++基础知识(二)

    C 基础知识 二 文章目录 C 基础知识 二 1 指针与引用 2 日期与时间 3 cerr与clog 1 指针与引用 C 有两种指针运算符 一种是取地址运算符 另一种是间接寻址运算符 它们都是单目运算符 返回操作数的内存地址 如 var读作
  • Vulkan【15】图形管线(Graphics Pipline)

    创建图形管线 本节的代码是 14 init pipeline cpp 你越来越接近把这些拉到一起来渲染一个立方体 下一步是通过设置图形管道来配置GPU来进行渲染 一个图形管线由着色阶段 管线布局 渲染过程和固定功能管线阶段组成 您在前面的部