先看看fence的使用
1、创建fence
VkFenceCreateInfo fenceInfo{VK_STRUCTURE_TYPE_FENCE_CREATE_INFO};
XRC_CHECK_THROW_VKCMD(vkCreateFence(m_vkDevice, &fenceInfo, nullptr, &execFence));
2、fence标记任务
VkSubmitInfo submitInfo{VK_STRUCTURE_TYPE_SUBMIT_INFO};
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &buf;
XRC_CHECK_THROW_VKCMD(vkQueueSubmit(queue, 1, &submitInfo, execFence));
3、等待任务执行完fence返回
返回1表示失败 0表示成功
auto res = vkWaitForFences(m_vkDevice, 1, &execFence, VK_TRUE, timeoutNs);
4、我们也可以主动查询fence的状态
vkGetFenceStatus(m_vkDevice,execFence)
Fences are a synchronization primitive that can be used to insert a dependency from a queue to the host. Fences have two states - signaled and unsignaled. A fence can be signaled as part of the execution of a queue submission command. Fences can be unsignaled on the host with vkResetFences. Fences can be waited on by the host with the vkWaitForFences command, and the current state can be queried with vkGetFenceStatus.
- 回到问题 :vkWaitForFences返回失败的情况
If the condition is satisfied whenvkWaitForFences
is called, thenvkWaitForFences
returns immediately. If the condition is not satisfied at the timevkWaitForFences
is called, thenvkWaitForFences
will block and wait until the condition is satisfied or thetimeout
has expired, whichever is sooner.
Iftimeout
is zero, thenvkWaitForFences
does not wait, but simply returns the current state of the fences.VK_TIMEOUT
will be returned in this case if the condition is not satisfied, even though no actual wait was performed.
If the condition is satisfied before thetimeout
has expired,vkWaitForFences
returnsVK_SUCCESS
. Otherwise,vkWaitForFences
returnsVK_TIMEOUT
after thetimeout
has expired.
If device loss occurs (see Lost Device) before the timeout has expired,vkWaitForFences
must return in finite time with eitherVK_SUCCESS
orVK_ERROR_DEVICE_LOST
.
遇到这个问题还伴随着一个现象:gpu使用率99%
大致可以猜到原因了:
要么vkQueueSubmit提交的东西比较大,gpu处理不过来
要么没有被消费,gpu处越堆越多
我遇到的情况是第二种!!!
相关性:如果说fence是gpu与cpu同步,那么emaphores 可以作为队列之间的同步
semaphores are a synchronization primitive that can be used to insert a dependency between queue operations or between a queue operation and the host. Binary semaphores have two states - signaled and unsignaled. Timeline semaphores have a strictly increasing 64-bit unsigned integer payload and are signaled with respect to a particular reference value. A semaphore can be signaled after execution of a queue operation is completed, and a queue operation can wait for a semaphore to become signaled before it begins execution. A timeline semaphore can additionally be signaled from the host with the vkSignalSemaphore command and waited on from the host with the vkWaitSemaphores command.
The internal data of a semaphore may include a reference to any resources and pending work associated with signal or unsignal operations performed on that semaphore object, collectively referred to as the semaphore’s payload. Mechanisms to import and export that internal data to and from semaphores are provided below. These mechanisms indirectly enable applications to share semaphore state between two or more semaphores and other synchronization primitives across process and API boundaries.