mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
d3d12memorycopy: Enhance d3d12 to d3d11 copy
If a d3d12 memory holds non-direct-queue fence but the fence was created with D3D12_FENCE_FLAG_SHARED flag, use the fence instead of waiting for fence at CPU side. Note that d3d12ipcsrc or d3d12screencapture elements will hold such sharable fence. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7139>
This commit is contained in:
parent
528fbe7b3c
commit
e692bf0fb9
1 changed files with 59 additions and 1 deletions
|
@ -123,6 +123,8 @@ struct _GstD3D12MemoryCopyPrivate
|
|||
|
||||
fence12 = nullptr;
|
||||
fence11 = nullptr;
|
||||
fence12_external = nullptr;
|
||||
fence11_external = nullptr;
|
||||
fence12_on_11 = nullptr;
|
||||
fence11_on_11 = nullptr;
|
||||
context11_4 = nullptr;
|
||||
|
@ -149,6 +151,9 @@ struct _GstD3D12MemoryCopyPrivate
|
|||
ComPtr < ID3D12Fence > fence12;
|
||||
ComPtr < ID3D11Fence > fence11;
|
||||
|
||||
ComPtr < ID3D12Fence > fence12_external;
|
||||
ComPtr < ID3D11Fence > fence11_external;
|
||||
|
||||
ComPtr < ID3D12Fence > fence12_on_11;
|
||||
ComPtr < ID3D11Fence > fence11_on_11;
|
||||
|
||||
|
@ -1254,6 +1259,9 @@ gst_d3d12_memory_copy_12_to_11 (GstD3D12MemoryCopy * self,
|
|||
if (gst_d3d12_memory_get_fence (in_mem12, &fence12, &fence_val)) {
|
||||
auto completed = fence12->GetCompletedValue ();
|
||||
if (completed < fence_val) {
|
||||
GST_TRACE_OBJECT (self, "Completed %" G_GUINT64_FORMAT
|
||||
" < WaitValue %" G_GUINT64_FORMAT, completed, fence_val);
|
||||
|
||||
if (fence12.Get () == priv->fence12.Get ()) {
|
||||
GstD3D11DeviceLockGuard lk (priv->device11);
|
||||
hr = priv->context11_4->Wait (priv->fence11.Get (), fence_val);
|
||||
|
@ -1263,8 +1271,58 @@ gst_d3d12_memory_copy_12_to_11 (GstD3D12MemoryCopy * self,
|
|||
gst_memory_unmap (in_mem, &in_map);
|
||||
return FALSE;
|
||||
}
|
||||
} else if (priv->fence12_external == fence12) {
|
||||
GST_LOG_OBJECT (self, "Reuse shared fence");
|
||||
GstD3D11DeviceLockGuard lk (priv->device11);
|
||||
hr = priv->context11_4->Wait (priv->fence11_external.Get (),
|
||||
fence_val);
|
||||
if (FAILED (hr)) {
|
||||
GST_ERROR_OBJECT (self, "Wait failed");
|
||||
gst_memory_unmap (out_mem, &out_map);
|
||||
gst_memory_unmap (in_mem, &in_map);
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
gst_d3d12_memory_sync (in_mem12);
|
||||
ComPtr < ID3D12Fence1 > fence12_1;
|
||||
bool need_sync = true;
|
||||
|
||||
hr = fence12.As (&fence12_1);
|
||||
if (SUCCEEDED (hr)) {
|
||||
if ((fence12_1->GetCreationFlags () & D3D12_FENCE_FLAG_SHARED) ==
|
||||
D3D12_FENCE_FLAG_SHARED) {
|
||||
auto device12 =
|
||||
gst_d3d12_device_get_device_handle (priv->device12);
|
||||
HANDLE handle;
|
||||
hr = device12->CreateSharedHandle (fence12.Get (), nullptr,
|
||||
GENERIC_ALL, nullptr, &handle);
|
||||
if (SUCCEEDED (hr)) {
|
||||
ComPtr < ID3D11Fence > fence11;
|
||||
hr = priv->device11_5->OpenSharedFence (handle,
|
||||
IID_PPV_ARGS (&fence11));
|
||||
CloseHandle (handle);
|
||||
|
||||
if (SUCCEEDED (hr)) {
|
||||
GST_DEBUG_OBJECT (self, "Opened new external shared fence");
|
||||
priv->fence12_external = fence12;
|
||||
priv->fence11_external = fence11;
|
||||
|
||||
GstD3D11DeviceLockGuard lk (priv->device11);
|
||||
hr = priv->context11_4->Wait (fence11.Get (), fence_val);
|
||||
if (FAILED (hr)) {
|
||||
GST_ERROR_OBJECT (self, "Wait failed");
|
||||
gst_memory_unmap (out_mem, &out_map);
|
||||
gst_memory_unmap (in_mem, &in_map);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
need_sync = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (need_sync)
|
||||
gst_d3d12_memory_sync (in_mem12);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue