mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 05:10:11 +01:00
venus: allow timeline semaphore feedback to suspend and resume
Similar idea with fence feedback, but a bit tricky in the resume condition. See comments for details. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38049>
This commit is contained in:
parent
ecb385f088
commit
13e9bc2ff9
3 changed files with 70 additions and 13 deletions
|
|
@ -6,7 +6,3 @@ dEQP-VK.api.external.memory.android_hardware_buffer.*
|
||||||
# only APKs support window creation on Android.
|
# only APKs support window creation on Android.
|
||||||
dEQP-VK.image.swapchain_mutable.*
|
dEQP-VK.image.swapchain_mutable.*
|
||||||
dEQP-VK.wsi.*
|
dEQP-VK.wsi.*
|
||||||
|
|
||||||
# Skip for now. The test is creating video queues without enabling video
|
|
||||||
# extensions. To be clarified at spec level.
|
|
||||||
dEQP-VK.synchronization*
|
|
||||||
|
|
|
||||||
|
|
@ -422,6 +422,7 @@ static void
|
||||||
vn_queue_submission_count_batch_feedback(struct vn_queue_submission *submit,
|
vn_queue_submission_count_batch_feedback(struct vn_queue_submission *submit,
|
||||||
uint32_t batch_index)
|
uint32_t batch_index)
|
||||||
{
|
{
|
||||||
|
struct vn_queue *queue = vn_queue_from_handle(submit->queue_handle);
|
||||||
const uint32_t signal_count =
|
const uint32_t signal_count =
|
||||||
vn_get_signal_semaphore_count(submit, batch_index);
|
vn_get_signal_semaphore_count(submit, batch_index);
|
||||||
uint32_t extra_cmd_count = 0;
|
uint32_t extra_cmd_count = 0;
|
||||||
|
|
@ -431,8 +432,17 @@ vn_queue_submission_count_batch_feedback(struct vn_queue_submission *submit,
|
||||||
struct vn_semaphore *sem = vn_semaphore_from_handle(
|
struct vn_semaphore *sem = vn_semaphore_from_handle(
|
||||||
vn_get_signal_semaphore(submit, batch_index, i));
|
vn_get_signal_semaphore(submit, batch_index, i));
|
||||||
if (sem->feedback.slot) {
|
if (sem->feedback.slot) {
|
||||||
feedback_types |= VN_FEEDBACK_TYPE_SEMAPHORE;
|
if (queue->can_feedback) {
|
||||||
extra_cmd_count++;
|
feedback_types |= VN_FEEDBACK_TYPE_SEMAPHORE;
|
||||||
|
extra_cmd_count++;
|
||||||
|
} else {
|
||||||
|
const uint64_t counter =
|
||||||
|
vn_get_signal_semaphore_counter(submit, batch_index, i);
|
||||||
|
simple_mtx_lock(&sem->feedback.counter_mtx);
|
||||||
|
sem->feedback.suspended_counter = counter;
|
||||||
|
sem->feedback.pollable = false;
|
||||||
|
simple_mtx_unlock(&sem->feedback.counter_mtx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -814,6 +824,7 @@ static VkResult
|
||||||
vn_queue_submission_setup_batch(struct vn_queue_submission *submit,
|
vn_queue_submission_setup_batch(struct vn_queue_submission *submit,
|
||||||
uint32_t batch_index)
|
uint32_t batch_index)
|
||||||
{
|
{
|
||||||
|
struct vn_queue *queue = vn_queue_from_handle(submit->queue_handle);
|
||||||
uint32_t feedback_types = 0;
|
uint32_t feedback_types = 0;
|
||||||
uint32_t extra_cmd_count = 0;
|
uint32_t extra_cmd_count = 0;
|
||||||
|
|
||||||
|
|
@ -822,7 +833,7 @@ vn_queue_submission_setup_batch(struct vn_queue_submission *submit,
|
||||||
for (uint32_t i = 0; i < signal_count; i++) {
|
for (uint32_t i = 0; i < signal_count; i++) {
|
||||||
struct vn_semaphore *sem = vn_semaphore_from_handle(
|
struct vn_semaphore *sem = vn_semaphore_from_handle(
|
||||||
vn_get_signal_semaphore(submit, batch_index, i));
|
vn_get_signal_semaphore(submit, batch_index, i));
|
||||||
if (sem->feedback.slot) {
|
if (sem->feedback.slot && queue->can_feedback) {
|
||||||
feedback_types |= VN_FEEDBACK_TYPE_SEMAPHORE;
|
feedback_types |= VN_FEEDBACK_TYPE_SEMAPHORE;
|
||||||
extra_cmd_count++;
|
extra_cmd_count++;
|
||||||
}
|
}
|
||||||
|
|
@ -2048,6 +2059,7 @@ vn_semaphore_feedback_init(struct vn_device *dev,
|
||||||
|
|
||||||
sem->feedback.signaled_counter = initial_value;
|
sem->feedback.signaled_counter = initial_value;
|
||||||
sem->feedback.slot = slot;
|
sem->feedback.slot = slot;
|
||||||
|
sem->feedback.pollable = true;
|
||||||
|
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -2169,7 +2181,13 @@ vn_GetSemaphoreCounterValue(VkDevice device,
|
||||||
|
|
||||||
assert(payload->type == VN_SYNC_TYPE_DEVICE_ONLY);
|
assert(payload->type == VN_SYNC_TYPE_DEVICE_ONLY);
|
||||||
|
|
||||||
if (sem->feedback.slot) {
|
if (sem->feedback.pollable) {
|
||||||
|
assert(sem->feedback.slot);
|
||||||
|
|
||||||
|
/* If we are here when feedback is suspended, signaled_counter has been
|
||||||
|
* updated to the suspended counter value which must be greater than the
|
||||||
|
* feedback counter read from the feedback slot.
|
||||||
|
*/
|
||||||
simple_mtx_lock(&sem->feedback.counter_mtx);
|
simple_mtx_lock(&sem->feedback.counter_mtx);
|
||||||
const uint64_t counter = vn_feedback_get_counter(sem->feedback.slot);
|
const uint64_t counter = vn_feedback_get_counter(sem->feedback.slot);
|
||||||
if (sem->feedback.signaled_counter < counter) {
|
if (sem->feedback.signaled_counter < counter) {
|
||||||
|
|
@ -2222,11 +2240,30 @@ vn_GetSemaphoreCounterValue(VkDevice device,
|
||||||
simple_mtx_unlock(&sem->feedback.counter_mtx);
|
simple_mtx_unlock(&sem->feedback.counter_mtx);
|
||||||
|
|
||||||
*pValue = counter;
|
*pValue = counter;
|
||||||
return VK_SUCCESS;
|
|
||||||
} else {
|
} else {
|
||||||
return vn_call_vkGetSemaphoreCounterValue(dev->primary_ring, device,
|
VkResult result = vn_call_vkGetSemaphoreCounterValue(
|
||||||
semaphore, pValue);
|
dev->primary_ring, device, semaphore, pValue);
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
if (sem->feedback.slot) {
|
||||||
|
/* Keep suspended feedback slot counter up to date so that counter
|
||||||
|
* query won't go backwards when feedback gets resumed.
|
||||||
|
*
|
||||||
|
* Keep suspended_counter up to date so that the feedback slot counter
|
||||||
|
* won't go backwards. e.g. multiple threads querying when suspended
|
||||||
|
*/
|
||||||
|
simple_mtx_lock(&sem->feedback.counter_mtx);
|
||||||
|
if (*pValue >= sem->feedback.suspended_counter) {
|
||||||
|
vn_feedback_set_counter(sem->feedback.slot, *pValue);
|
||||||
|
sem->feedback.suspended_counter = *pValue;
|
||||||
|
sem->feedback.pollable = true;
|
||||||
|
}
|
||||||
|
simple_mtx_unlock(&sem->feedback.counter_mtx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkResult
|
VkResult
|
||||||
|
|
@ -2247,6 +2284,7 @@ vn_SignalSemaphore(VkDevice device, const VkSemaphoreSignalInfo *pSignalInfo)
|
||||||
* the renderer.
|
* the renderer.
|
||||||
*/
|
*/
|
||||||
sem->feedback.signaled_counter = pSignalInfo->value;
|
sem->feedback.signaled_counter = pSignalInfo->value;
|
||||||
|
sem->feedback.pollable = true;
|
||||||
|
|
||||||
simple_mtx_unlock(&sem->feedback.counter_mtx);
|
simple_mtx_unlock(&sem->feedback.counter_mtx);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -131,12 +131,35 @@ struct vn_semaphore {
|
||||||
/* Lock for accessing free/pending sfb cmds */
|
/* Lock for accessing free/pending sfb cmds */
|
||||||
simple_mtx_t cmd_mtx;
|
simple_mtx_t cmd_mtx;
|
||||||
|
|
||||||
/* Cached counter value to track if an async sem wait call is needed */
|
/* Indicate whether the timeline semaphore counter value in the feedback
|
||||||
uint64_t signaled_counter;
|
* slot is pollable. When pollable is false, the semaphore feedback has
|
||||||
|
* been suspended and the slot won't be signaled to the pending counter.
|
||||||
|
* - suspend: submit on queues not supporting feedback
|
||||||
|
* - resume if any of below occurs:
|
||||||
|
* - vn_SignalSemaphore
|
||||||
|
* - when the queried counter value is no smaller than the suspended
|
||||||
|
* counter value
|
||||||
|
*/
|
||||||
|
bool pollable;
|
||||||
|
|
||||||
|
/* When feedback is active, signaled_counter is the cached counter value
|
||||||
|
* to track if an async sem wait call is needed.
|
||||||
|
*
|
||||||
|
* When feedback is suspended, suspended_counter tracks the greatest
|
||||||
|
* signal counter value submitted on queues not supporting feedback.
|
||||||
|
*
|
||||||
|
* They share the same storage and the value is monotonic.
|
||||||
|
*/
|
||||||
|
union {
|
||||||
|
uint64_t signaled_counter;
|
||||||
|
uint64_t suspended_counter;
|
||||||
|
};
|
||||||
|
|
||||||
/* Lock for checking if an async sem wait call is needed based on
|
/* Lock for checking if an async sem wait call is needed based on
|
||||||
* the current counter value and signaled_counter to ensure async
|
* the current counter value and signaled_counter to ensure async
|
||||||
* wait order across threads.
|
* wait order across threads.
|
||||||
|
*
|
||||||
|
* Also lock to protect suspended_counter and pollable updates.
|
||||||
*/
|
*/
|
||||||
simple_mtx_t counter_mtx;
|
simple_mtx_t counter_mtx;
|
||||||
} feedback;
|
} feedback;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue