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可以被不同的线程写入

网友评论