mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-18 07:47:17 +00:00
d3d11: Port to GstD3D11Fence
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2790>
This commit is contained in:
parent
ba259111d5
commit
6fff608f27
6 changed files with 76 additions and 88 deletions
|
@ -58,6 +58,7 @@ struct _GstAmfEncoderPrivate
|
|||
const wchar_t *codec_id;
|
||||
|
||||
GstD3D11Device *device;
|
||||
GstD3D11Fence *fence;
|
||||
AMFContext *context;
|
||||
AMFComponent *comp;
|
||||
GstBufferPool *internal_pool;
|
||||
|
@ -439,6 +440,7 @@ gst_amf_encoder_close (GstVideoEncoder * encoder)
|
|||
priv->context = nullptr;
|
||||
}
|
||||
|
||||
gst_clear_d3d11_fence (&priv->fence);
|
||||
gst_clear_object (&priv->device);
|
||||
|
||||
return TRUE;
|
||||
|
@ -617,9 +619,6 @@ gst_amf_encoder_copy_d3d11 (GstAmfEncoder * self, GstBuffer * src_buffer,
|
|||
GstFlowReturn ret;
|
||||
ComPtr < IDXGIResource > dxgi_resource;
|
||||
ComPtr < ID3D11Texture2D > shared_texture;
|
||||
ComPtr < ID3D11Query > query;
|
||||
D3D11_QUERY_DESC query_desc;
|
||||
BOOL sync_done = FALSE;
|
||||
HANDLE shared_handle;
|
||||
GstD3D11Device *device;
|
||||
HRESULT hr;
|
||||
|
@ -699,13 +698,14 @@ gst_amf_encoder_copy_d3d11 (GstAmfEncoder * self, GstBuffer * src_buffer,
|
|||
src_box.bottom = MIN (src_desc.Height, dst_desc.Height);
|
||||
|
||||
if (shared) {
|
||||
query_desc.Query = D3D11_QUERY_EVENT;
|
||||
query_desc.MiscFlags = 0;
|
||||
if (priv->fence && priv->fence->device != device)
|
||||
gst_clear_d3d11_fence (&priv->fence);
|
||||
|
||||
hr = device_handle->CreateQuery (&query_desc, &query);
|
||||
if (!gst_d3d11_result (hr, device)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't Create event query, hr: 0x%x",
|
||||
(guint) hr);
|
||||
if (!priv->fence)
|
||||
priv->fence = gst_d3d11_device_create_fence (device);
|
||||
|
||||
if (!priv->fence) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't crete fence");
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -716,15 +716,11 @@ gst_amf_encoder_copy_d3d11 (GstAmfEncoder * self, GstBuffer * src_buffer,
|
|||
0, 0, 0, src_tex, subresource_idx, &src_box);
|
||||
|
||||
if (shared) {
|
||||
device_context->End (query.Get ());
|
||||
do {
|
||||
hr = device_context->GetData (query.Get (), &sync_done, sizeof (BOOL), 0);
|
||||
} while (!sync_done && (hr == S_OK || hr == S_FALSE));
|
||||
|
||||
if (!gst_d3d11_result (hr, device)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't sync GPU operation, hr: 0x%x",
|
||||
(guint) hr);
|
||||
if (!gst_d3d11_fence_signal (priv->fence) ||
|
||||
!gst_d3d11_fence_wait (priv->fence)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't sync GPU operation");
|
||||
gst_d3d11_device_unlock (device);
|
||||
gst_clear_d3d11_fence (&priv->fence);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
|
|
@ -231,6 +231,7 @@ class D3D11DesktopDupObject
|
|||
public:
|
||||
D3D11DesktopDupObject ()
|
||||
: device_(nullptr)
|
||||
, fence_(nullptr)
|
||||
, metadata_buffer_(nullptr)
|
||||
, metadata_buffer_size_(0)
|
||||
, vertex_buffer_(nullptr)
|
||||
|
@ -246,6 +247,7 @@ public:
|
|||
if (vertex_buffer_)
|
||||
delete[] vertex_buffer_;
|
||||
|
||||
gst_clear_d3d11_fence (&fence_);
|
||||
gst_clear_object (&device_);
|
||||
}
|
||||
|
||||
|
@ -545,8 +547,8 @@ public:
|
|||
{
|
||||
ID3D11DeviceContext *context_handle = nullptr;
|
||||
ComPtr <ID3D11Texture2D> tex;
|
||||
ComPtr < ID3D11Query > query;
|
||||
HRESULT hr;
|
||||
gboolean is_shared = FALSE;
|
||||
|
||||
context_handle = gst_d3d11_device_get_device_context_handle (device);
|
||||
|
||||
|
@ -555,7 +557,6 @@ public:
|
|||
} else {
|
||||
ID3D11Device *device_handle = nullptr;
|
||||
ComPtr < IDXGIResource > dxgi_resource;
|
||||
D3D11_QUERY_DESC query_desc;
|
||||
HANDLE shared_handle;
|
||||
|
||||
device_handle = gst_d3d11_device_get_device_handle (device);
|
||||
|
@ -573,24 +574,24 @@ public:
|
|||
if (!gst_d3d11_result (hr, device))
|
||||
return GST_FLOW_ERROR;
|
||||
|
||||
query_desc.Query = D3D11_QUERY_EVENT;
|
||||
query_desc.MiscFlags = 0;
|
||||
if (fence_ && fence_->device != device)
|
||||
gst_clear_d3d11_fence (&fence_);
|
||||
|
||||
hr = device_handle->CreateQuery (&query_desc, &query);
|
||||
if (!gst_d3d11_result (hr, device))
|
||||
if (!fence_)
|
||||
fence_ = gst_d3d11_device_create_fence (device);
|
||||
|
||||
if (!fence_)
|
||||
return GST_FLOW_ERROR;
|
||||
|
||||
is_shared = TRUE;
|
||||
}
|
||||
|
||||
context_handle->CopySubresourceRegion (texture, 0, 0, 0, 0,
|
||||
tex.Get(), 0, cropBox);
|
||||
tex.Get(), 0, cropBox);
|
||||
|
||||
if (query) {
|
||||
BOOL sync_done = FALSE;
|
||||
|
||||
do {
|
||||
hr = context_handle->GetData (query.Get (),
|
||||
&sync_done, sizeof (BOOL), 0);
|
||||
} while (!sync_done && (hr == S_OK || hr == S_FALSE));
|
||||
if (is_shared) {
|
||||
if (!gst_d3d11_fence_signal (fence_) || !gst_d3d11_fence_wait (fence_))
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
return GST_FLOW_OK;
|
||||
|
@ -1471,6 +1472,7 @@ private:
|
|||
PTR_INFO ptr_info_;
|
||||
DXGI_OUTDUPL_DESC output_desc_;
|
||||
GstD3D11Device * device_;
|
||||
GstD3D11Fence * fence_;
|
||||
|
||||
ComPtr<ID3D11Texture2D> shared_texture_;
|
||||
ComPtr<ID3D11RenderTargetView> rtv_;
|
||||
|
|
|
@ -40,6 +40,8 @@ struct _GstD3D11WindowDummy
|
|||
ID3D11Texture2D *fallback_texture;
|
||||
ID3D11VideoProcessorOutputView *fallback_pov;
|
||||
ID3D11RenderTargetView *fallback_rtv;
|
||||
|
||||
GstD3D11Fence *fence;
|
||||
};
|
||||
|
||||
#define gst_d3d11_window_dummy_parent_class parent_class
|
||||
|
@ -50,6 +52,7 @@ static void gst_d3d11_window_dummy_on_resize (GstD3D11Window * window,
|
|||
guint width, guint height);
|
||||
static gboolean gst_d3d11_window_dummy_prepare (GstD3D11Window * window,
|
||||
guint display_width, guint display_height, GstCaps * caps, GError ** error);
|
||||
static void gst_d3d11_window_dummy_unprepare (GstD3D11Window * window);
|
||||
static gboolean
|
||||
gst_d3d11_window_dummy_open_shared_handle (GstD3D11Window * window,
|
||||
GstD3D11WindowSharedHandleData * data);
|
||||
|
@ -65,6 +68,8 @@ gst_d3d11_window_dummy_class_init (GstD3D11WindowDummyClass * klass)
|
|||
window_class->on_resize =
|
||||
GST_DEBUG_FUNCPTR (gst_d3d11_window_dummy_on_resize);
|
||||
window_class->prepare = GST_DEBUG_FUNCPTR (gst_d3d11_window_dummy_prepare);
|
||||
window_class->unprepare =
|
||||
GST_DEBUG_FUNCPTR (gst_d3d11_window_dummy_unprepare);
|
||||
window_class->open_shared_handle =
|
||||
GST_DEBUG_FUNCPTR (gst_d3d11_window_dummy_open_shared_handle);
|
||||
window_class->release_shared_handle =
|
||||
|
@ -144,6 +149,14 @@ gst_d3d11_window_dummy_prepare (GstD3D11Window * window,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_d3d11_window_dummy_unprepare (GstD3D11Window * window)
|
||||
{
|
||||
GstD3D11WindowDummy *self = GST_D3D11_WINDOW_DUMMY (window);
|
||||
|
||||
gst_clear_d3d11_fence (&self->fence);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_d3d11_window_dummy_on_resize (GstD3D11Window * window,
|
||||
guint width, guint height)
|
||||
|
@ -286,34 +299,19 @@ gst_d3d11_window_dummy_release_shared_handle (GstD3D11Window * window,
|
|||
|
||||
GST_D3D11_CLEAR_COM (data->keyed_mutex);
|
||||
} else {
|
||||
/* *INDENT-OFF* */
|
||||
ComPtr<ID3D11Query> query;
|
||||
/* *INDENT-ON* */
|
||||
D3D11_QUERY_DESC query_desc;
|
||||
ID3D11Device *device_handle = gst_d3d11_device_get_device_handle (device);
|
||||
ID3D11DeviceContext *context_handle =
|
||||
gst_d3d11_device_get_device_context_handle (device);
|
||||
BOOL sync_done = FALSE;
|
||||
|
||||
/* If keyed mutex is not used, let's handle sync manually by using
|
||||
* ID3D11Query. Issued GPU commands might not be finished yet */
|
||||
query_desc.Query = D3D11_QUERY_EVENT;
|
||||
query_desc.MiscFlags = 0;
|
||||
* fence. Issued GPU commands might not be finished yet */
|
||||
|
||||
hr = device_handle->CreateQuery (&query_desc, &query);
|
||||
if (!gst_d3d11_result (hr, device)) {
|
||||
if (!self->fence)
|
||||
self->fence = gst_d3d11_device_create_fence (device);
|
||||
|
||||
if (!self->fence) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't Create event query");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
context_handle->End (query.Get ());
|
||||
|
||||
/* Wait until all issued GPU commands are finished */
|
||||
do {
|
||||
hr = context_handle->GetData (query.Get (), &sync_done, sizeof (BOOL), 0);
|
||||
} while (!sync_done && (hr == S_OK || hr == S_FALSE));
|
||||
|
||||
if (!gst_d3d11_result (hr, device)) {
|
||||
if (!gst_d3d11_fence_signal (self->fence) ||
|
||||
!gst_d3d11_fence_wait (self->fence)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't sync GPU operation");
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -264,6 +264,7 @@ gst_mf_video_encoder_close (GstVideoEncoder * enc)
|
|||
|
||||
gst_clear_object (&self->other_d3d11_device);
|
||||
gst_clear_object (&self->d3d11_device);
|
||||
gst_clear_d3d11_fence (&self->fence);
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
|
@ -1064,9 +1065,6 @@ gst_mf_video_encoder_create_input_sample_d3d11 (GstMFVideoEncoder * self,
|
|||
ComPtr < ID3D11Texture2D > mf_texture;
|
||||
ComPtr < IDXGIResource > dxgi_resource;
|
||||
ComPtr < ID3D11Texture2D > shared_texture;
|
||||
ComPtr < ID3D11Query > query;
|
||||
D3D11_QUERY_DESC query_desc;
|
||||
BOOL sync_done = FALSE;
|
||||
HANDLE shared_handle;
|
||||
GstMemory *mem;
|
||||
GstD3D11Memory *dmem;
|
||||
|
@ -1171,30 +1169,27 @@ gst_mf_video_encoder_create_input_sample_d3d11 (GstMFVideoEncoder * self,
|
|||
src_box.right = MIN (src_desc.Width, dst_desc.Width);
|
||||
src_box.bottom = MIN (src_desc.Height, dst_desc.Height);
|
||||
|
||||
/* CopySubresourceRegion() might not be able to guarantee
|
||||
* copying. To ensure it, we will make use of d3d11 query */
|
||||
query_desc.Query = D3D11_QUERY_EVENT;
|
||||
query_desc.MiscFlags = 0;
|
||||
gst_d3d11_device_lock (dmem->device);
|
||||
if (self->fence && self->fence->device != dmem->device)
|
||||
gst_clear_d3d11_fence (&self->fence);
|
||||
|
||||
hr = device_handle->CreateQuery (&query_desc, &query);
|
||||
if (!gst_d3d11_result (hr, dmem->device)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't Create event query");
|
||||
if (!self->fence)
|
||||
self->fence = gst_d3d11_device_create_fence (dmem->device);
|
||||
|
||||
if (!self->fence) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't create fence object");
|
||||
gst_d3d11_device_unlock (dmem->device);
|
||||
gst_memory_unmap (mem, &info);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gst_d3d11_device_lock (dmem->device);
|
||||
context_handle->CopySubresourceRegion (shared_texture.Get (), 0, 0, 0, 0,
|
||||
texture, subidx, &src_box);
|
||||
context_handle->End (query.Get ());
|
||||
|
||||
/* Wait until all issued GPU commands are finished */
|
||||
do {
|
||||
hr = context_handle->GetData (query.Get (), &sync_done, sizeof (BOOL), 0);
|
||||
} while (!sync_done && (hr == S_OK || hr == S_FALSE));
|
||||
|
||||
if (!gst_d3d11_result (hr, dmem->device)) {
|
||||
if (!gst_d3d11_fence_signal (self->fence) ||
|
||||
!gst_d3d11_fence_wait (self->fence)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't sync GPU operation");
|
||||
gst_clear_d3d11_fence (&self->fence);
|
||||
gst_d3d11_device_unlock (dmem->device);
|
||||
gst_memory_unmap (mem, &info);
|
||||
|
||||
|
|
|
@ -116,6 +116,7 @@ struct _GstMFVideoEncoder
|
|||
IMFDXGIDeviceManager *device_manager;
|
||||
UINT reset_token;
|
||||
IMFVideoSampleAllocatorEx *mf_allocator;
|
||||
GstD3D11Fence *fence;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ struct _GstNvEncoderPrivate
|
|||
GstCudaContext *context;
|
||||
#ifdef GST_CUDA_HAS_D3D
|
||||
GstD3D11Device *device;
|
||||
GstD3D11Fence *fence;
|
||||
#endif
|
||||
|
||||
GstNvEncoderDeviceMode subclass_device_mode;
|
||||
|
@ -439,6 +440,7 @@ gst_nv_encoder_close (GstVideoEncoder * encoder)
|
|||
|
||||
gst_clear_object (&priv->context);
|
||||
#ifdef GST_CUDA_HAS_D3D
|
||||
gst_clear_d3d11_fence (&priv->fence);
|
||||
gst_clear_object (&priv->device);
|
||||
#endif
|
||||
|
||||
|
@ -1558,9 +1560,6 @@ gst_nv_encoder_copy_d3d11 (GstNvEncoder * self,
|
|||
GstFlowReturn ret;
|
||||
ComPtr < IDXGIResource > dxgi_resource;
|
||||
ComPtr < ID3D11Texture2D > shared_texture;
|
||||
ComPtr < ID3D11Query > query;
|
||||
D3D11_QUERY_DESC query_desc;
|
||||
BOOL sync_done = FALSE;
|
||||
HANDLE shared_handle;
|
||||
GstD3D11Device *device;
|
||||
HRESULT hr;
|
||||
|
@ -1639,13 +1638,14 @@ gst_nv_encoder_copy_d3d11 (GstNvEncoder * self,
|
|||
src_box.bottom = MIN (src_desc.Height, dst_desc.Height);
|
||||
|
||||
if (shared) {
|
||||
query_desc.Query = D3D11_QUERY_EVENT;
|
||||
query_desc.MiscFlags = 0;
|
||||
if (priv->fence && priv->fence->device != device)
|
||||
gst_clear_d3d11_fence (&priv->fence);
|
||||
|
||||
hr = device_handle->CreateQuery (&query_desc, &query);
|
||||
if (!gst_d3d11_result (hr, device)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't Create event query, hr: 0x%x",
|
||||
(guint) hr);
|
||||
if (!priv->fence)
|
||||
priv->fence = gst_d3d11_device_create_fence (device);
|
||||
|
||||
if (!priv->fence) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't crete fence");
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -1656,15 +1656,11 @@ gst_nv_encoder_copy_d3d11 (GstNvEncoder * self,
|
|||
0, 0, 0, src_tex, subresource_idx, &src_box);
|
||||
|
||||
if (shared) {
|
||||
device_context->End (query.Get ());
|
||||
do {
|
||||
hr = device_context->GetData (query.Get (), &sync_done, sizeof (BOOL), 0);
|
||||
} while (!sync_done && (hr == S_OK || hr == S_FALSE));
|
||||
|
||||
if (!gst_d3d11_result (hr, device)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't sync GPU operation, hr: 0x%x",
|
||||
(guint) hr);
|
||||
if (!gst_d3d11_fence_signal (priv->fence) ||
|
||||
!gst_d3d11_fence_wait (priv->fence)) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't sync GPU operation");
|
||||
gst_d3d11_device_unlock (device);
|
||||
gst_clear_d3d11_fence (&priv->fence);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue