d3d12fence: Check completed value before waiting

If currently completed fence value is larger than target value,
skip waiting.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5356>
This commit is contained in:
Seungha Yang 2023-09-19 18:57:53 +09:00 committed by GStreamer Marge Bot
parent 5b252a1511
commit 44b02e58fc

View file

@ -51,7 +51,6 @@ struct _GstD3D12FencePrivate
HANDLE event_handle; HANDLE event_handle;
std::mutex lock; std::mutex lock;
guint64 value = 0; guint64 value = 0;
gboolean can_wait = FALSE;
}; };
/* *INDENT-ON* */ /* *INDENT-ON* */
@ -108,21 +107,15 @@ gst_d3d12_fence_set_event_on_completion_value (GstD3D12Fence * fence,
guint64 value) guint64 value)
{ {
GstD3D12FencePrivate *priv; GstD3D12FencePrivate *priv;
HRESULT hr;
g_return_val_if_fail (fence != nullptr, FALSE); g_return_val_if_fail (fence != nullptr, FALSE);
priv = fence->priv; priv = fence->priv;
std::lock_guard < std::mutex > lk (priv->lock); std::lock_guard < std::mutex > lk (priv->lock);
hr = priv->fence->SetEventOnCompletion (value, priv->event_handle); auto current = priv->fence->GetCompletedValue ();
if (!gst_d3d12_result (hr, fence->device)) { if (value > current)
GST_ERROR_OBJECT (fence->device, "Failed to set completion event");
return FALSE;
}
priv->value = value; priv->value = value;
priv->can_wait = TRUE;
return TRUE; return TRUE;
} }
@ -143,15 +136,27 @@ gst_d3d12_fence_wait_for (GstD3D12Fence * fence, guint timeout_ms)
GstD3D12FencePrivate *priv = fence->priv; GstD3D12FencePrivate *priv = fence->priv;
std::lock_guard < std::mutex > lk (priv->lock); std::lock_guard < std::mutex > lk (priv->lock);
if (!priv->can_wait) if (!priv->value)
return; return;
GST_TRACE ("Waiting for fence to be signalled with value %" G_GUINT64_FORMAT, auto current = priv->fence->GetCompletedValue ();
priv->value); if (current < priv->value) {
HRESULT hr;
GST_TRACE ("Waiting for fence to be signalled with value %" G_GUINT64_FORMAT
", current: %" G_GUINT64_FORMAT, priv->value, current);
hr = priv->fence->SetEventOnCompletion (priv->value, priv->event_handle);
if (!gst_d3d12_result (hr, fence->device)) {
GST_ERROR_OBJECT (fence->device, "Failed to set completion event");
return;
}
WaitForSingleObjectEx (priv->event_handle, timeout_ms, FALSE); WaitForSingleObjectEx (priv->event_handle, timeout_ms, FALSE);
GST_TRACE ("Signalled with value %" G_GUINT64_FORMAT, priv->value); GST_TRACE ("Signalled with value %" G_GUINT64_FORMAT, priv->value);
} else {
priv->can_wait = FALSE; GST_TRACE ("target %" G_GUINT64_FORMAT " <= target: %" G_GUINT64_FORMAT,
priv->value, current);
}
} }
void void