Vulkan多线程渲染

2021-09-01  本文已影响0人  blue_lights

Vulkan是线程友好的渲染API

•应用程序层面的线程继续流行

•应用程序希望从多个线程生成渲染工作

•在多个线程中分散验证和提交成本

.应用程序通常可以在比驱动程序更高的级别上处理对象/访问同步

单线程调度会出现主线程阻塞 其他CPU饥饿现象。

主线程阻塞 其他线程空闲

在Vulkan中鼓励使用线程

•线程更新资源(缓冲区)

•CPU顶点数据或实例数据动画(例如变形)

•并行管道状态创建

•“着色器编译”和状态验证

•线程渲染/绘制调用

在多个线程中生成命令缓冲区

工作规范:命令缓冲区

•所有Vulkan渲染是通过命令缓冲区 驱动程序可以相应地优化缓冲区

•允许静态工作被重用

重要提示:没有状态会被跨命令缓冲区继承!


工作执行:队列

•不需要为了提交工作而“绑定一个上下文”

•多个线程可以提交工作到不同的队列

•队列通过CommandBuffer提交接受GPU工作

•队列有非常少的操作:本质上,“提交工作”和“等待空闲”

•在处理提交的工作之前等待

•当提交的工作完成时发出信号

排队的“家庭”可以接受不同类型的工作,例如。

•队列中的一种工作形式(例如DMA/内存仅传输队列)

工作协调:同步

信号量

•用于同步跨队列或跨粗粒度提交到单个队列的工作

事件和障碍

•用于同步命令缓冲区内的工作或提交到单个队列的命令缓冲区序列

栅栏

•用于同步设备与主机之间的工作。

命令缓冲区生成

命令缓冲区线程安全

•必须不回收CommandBuffer重写,直到它不再飞行

•但我们不想每帧都刷新队列!

•当命令缓冲区准备被回收时,VkFences可以提供一个队列提交来测试

改写命令缓冲区

GPU消耗队列

Vulkan线程:命令池

•VkCommandPool对象是关键的线程命令生成•VkCommandBuffers被分配从“父”VkCommandPool•VkCommandBuffers写入到不同的线程必须来自不同的池

•否则缓冲区和池都必须是外部同步的,这是不值得的

Vulkan线程:描述符池

•VkDescriptorPool对象可能需要线程对象状态生成

例如:sampler, uniform buffer,等等

•在创建池时指定的每种类型的最大数量

•vkdescriptorset从“父”VkDescriptorPool中分配

•在不同线程中分配的描述符必须来自不同的池

但是同一个池中的VkDescriptorSets可以被不同的线程写入

上一篇 下一篇

猜你喜欢

热点阅读