vulkan学习(六)——指令系统
一、指令与多线程理论
1.1 概念理解
指令
:在Vulkan当中,各类指令例如:VBO,绑定Uniform,绘制,更改格式等,都是通过Command进行,所以我们的任务就是设置任务缓冲,放入队列执行。
指令缓冲
:从CPU到GPU发送指令并且执行是一件非常耗费时间的行为,所以我们需要把指令及其参数录制到一个CommandBuffer当中,统一提交给GPU,使其可以一口气执行。
录制
:指令缓冲其实就是一个CPU的内存空间,Vulkan将我们输入的指令以及参数,做成机器可读的二进制数据,存放在这个内存空间,这个过程就是指令录制。
eg:
//录制指令命令
vkCmdBindPipeline(CommandBuffer, VK_PIPELINE_BIND_GRAPHICS, graphicsPipeline);
commandBuffer: 指向指令缓冲的句柄
VK_PIPELINE_BIND_POINT_GRAPHICS: 参数,表示用于绘制图像的管线对象
graphicsPipeline: 表示绑定的那条管线的句柄
后两个参数会被序列化为二进制数据,然后放在commandBuffer管理的内存当中。
PrimaryCommandBuffer
:主指令缓冲,用于直接向GPU提交出去的指令缓冲。
SdcondaryCommandBuffer
: 二级指令缓冲,可以将指令录制进去,然后把此指令缓冲送入主指令缓冲当中执行。
为什么要设计两种指令缓冲:
- 一般程序设计中,每个Object都会为其分配一个二级指令缓冲,用于录制自己的指令。eg:有的Object使用的管线,不需要推送Uniform,有的需要推送Constant。
- 方便使用多线程渲染。
单线程(OpenGL)渲染的问题
传统OpenGL渲染方式,保留着状态机模型,且是单线程。
DrawCall
在CPU端将一个物体的VBO绑定、纹理绑定等命令,做成指令,送入GPU队列执行的过程。
因此,如果有大量物体需要绘制,就需要大量的DrawCall,而且是线性执行,在CPU端就会损耗大量的时间,反而GPU空置下来,造成了流水线上的巨大浪费。
多线程渲染
二、图形绘制
问题:目前有绘制与显示两个命令提交,其中如何同步两个步骤呢?保证先绘制完毕,再提交;显示完毕再绘制新的?
答案:需要通过信号量(Semaphore)进行控制,可以让显示命令在渲染命令执行完毕之后继续开启,也可以让渲染命令在显示完毕后继续执行。
渲染等待显示的依赖示例
显示等待渲染的依赖
问题:
- 从交换链获取的图片是ImagePresentKHR的layout,但是渲染需要AttachmentOutputOptimal
- 渲染好的图片是AttachmentOutputOptimal,但是显示需要ImagePresentKHR
所以只使用信号量控制过程是不够的,怎么处理:
解答:
在RenderPass的SubPass当中,已经通过AttachmentDescription以及AttachmentReference对Image的格式变化做出了规定,所以除了PipelineStage层面的信号量,中间在进出SubPass以及整个RenderPass的时候,仍然会插入相关的Barrier自动格式转换。
- 点赞
- 收藏
- 关注作者
评论(0)