From 872b7f503c49442e559f6a381416c6a84b76a3c6 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Wed, 17 Mar 2021 23:53:04 +0900 Subject: d3d11: Enable native multi-thread protection layer and make use of it ... instead of our own GRecMutex locking. In this way, any other Direct3D11 client (MediaFoundation for example) can safely call any Direct3D11 API even when we are sharing our Direct3D11 device with others. Part-of: --- gst-libs/gst/d3d11/gstd3d11device.c | 28 +++++++++++++++++++++++----- gst-libs/gst/d3d11/gstd3d11memory.c | 11 ----------- gst-libs/gst/d3d11/meson.build | 2 +- 3 files changed, 24 insertions(+), 17 deletions(-) (limited to 'gst-libs/gst') diff --git a/gst-libs/gst/d3d11/gstd3d11device.c b/gst-libs/gst/d3d11/gstd3d11device.c index fd40ead5e..337bc19ce 100644 --- a/gst-libs/gst/d3d11/gstd3d11device.c +++ b/gst-libs/gst/d3d11/gstd3d11device.c @@ -30,6 +30,7 @@ #include #include +#include /** * SECTION:gstd3d11device @@ -105,11 +106,11 @@ struct _GstD3D11DevicePrivate ID3D11VideoDevice *video_device; ID3D11VideoContext *video_context; + ID3D10Multithread *multi_thread; IDXGIFactory1 *factory; GstD3D11Format format_table[GST_D3D11_N_FORMATS]; - GRecMutex extern_lock; GMutex resource_lock; #if HAVE_D3D11SDKLAYERS_H @@ -412,7 +413,6 @@ gst_d3d11_device_init (GstD3D11Device * self) priv = gst_d3d11_device_get_instance_private (self); priv->adapter = DEFAULT_ADAPTER; - g_rec_mutex_init (&priv->extern_lock); g_mutex_init (&priv->resource_lock); self->priv = priv; @@ -784,6 +784,20 @@ gst_d3d11_device_constructed (GObject * object) goto error; } + hr = ID3D11Device_QueryInterface (priv->device, &IID_ID3D10Multithread, + (void **) &priv->multi_thread); + if (!gst_d3d11_result (hr, NULL)) { + GST_ERROR_OBJECT (self, "ID3D10Multithread interface is not available"); + ID3D11Device_Release (priv->device); + priv->device = NULL; + + ID3D11DeviceContext_Release (priv->device_context); + priv->device_context = NULL; + goto error; + } + + ID3D10Multithread_SetMultithreadProtected (priv->multi_thread, TRUE); + priv->factory = factory; #if HAVE_D3D11SDKLAYERS_H @@ -899,6 +913,11 @@ gst_d3d11_device_dispose (GObject * object) GST_LOG_OBJECT (self, "dispose"); + if (priv->multi_thread) { + ID3D10Multithread_Release (priv->multi_thread); + priv->multi_thread = NULL; + } + if (priv->video_device) { ID3D11VideoDevice_Release (priv->video_device); priv->video_device = NULL; @@ -966,7 +985,6 @@ gst_d3d11_device_finalize (GObject * object) GST_LOG_OBJECT (self, "finalize"); - g_rec_mutex_clear (&priv->extern_lock); g_mutex_clear (&priv->resource_lock); g_free (priv->description); @@ -1148,7 +1166,7 @@ gst_d3d11_device_lock (GstD3D11Device * device) priv = device->priv; GST_TRACE_OBJECT (device, "device locking"); - g_rec_mutex_lock (&priv->extern_lock); + ID3D10Multithread_Enter (priv->multi_thread); GST_TRACE_OBJECT (device, "device locked"); } @@ -1169,8 +1187,8 @@ gst_d3d11_device_unlock (GstD3D11Device * device) g_return_if_fail (GST_IS_D3D11_DEVICE (device)); priv = device->priv; + ID3D10Multithread_Leave (priv->multi_thread); - g_rec_mutex_unlock (&priv->extern_lock); GST_TRACE_OBJECT (device, "device unlocked"); } diff --git a/gst-libs/gst/d3d11/gstd3d11memory.c b/gst-libs/gst/d3d11/gstd3d11memory.c index 0c96d7f31..da32c9e07 100644 --- a/gst-libs/gst/d3d11/gstd3d11memory.c +++ b/gst-libs/gst/d3d11/gstd3d11memory.c @@ -347,7 +347,6 @@ map_cpu_access_data (GstD3D11Memory * dmem, D3D11_MAP map_type) ID3D11DeviceContext *device_context = gst_d3d11_device_get_device_context_handle (dmem->device); - gst_d3d11_device_lock (dmem->device); if (GST_MEMORY_FLAG_IS_SET (dmem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD)) { ID3D11DeviceContext_CopySubresourceRegion (device_context, staging, 0, 0, 0, 0, texture, priv->subresource_index, NULL); @@ -362,8 +361,6 @@ map_cpu_access_data (GstD3D11Memory * dmem, D3D11_MAP map_type) ret = FALSE; } - gst_d3d11_device_unlock (dmem->device); - return ret; } @@ -383,7 +380,6 @@ gst_d3d11_memory_map_staging (GstMemory * mem, GstMapFlags flags) map_type = gst_map_flags_to_d3d11 (flags); - gst_d3d11_device_lock (dmem->device); hr = ID3D11DeviceContext_Map (device_context, (ID3D11Resource *) priv->texture, 0, map_type, 0, &priv->map); if (!gst_d3d11_result (hr, dmem->device)) { @@ -391,7 +387,6 @@ gst_d3d11_memory_map_staging (GstMemory * mem, GstMapFlags flags) "Failed to map staging texture (0x%x)", (guint) hr); ret = FALSE; } - gst_d3d11_device_unlock (dmem->device); if (!ret) { GST_D3D11_MEMORY_UNLOCK (dmem); @@ -425,11 +420,9 @@ gst_d3d11_memory_map (GstMemory * mem, gsize maxsize, GstMapFlags flags) ID3D11DeviceContext *device_context = gst_d3d11_device_get_device_context_handle (dmem->device); - gst_d3d11_device_lock (dmem->device); ID3D11DeviceContext_CopySubresourceRegion (device_context, (ID3D11Resource *) priv->texture, priv->subresource_index, 0, 0, 0, (ID3D11Resource *) priv->staging, 0, NULL); - gst_d3d11_device_unlock (dmem->device); } GST_MEMORY_FLAG_UNSET (dmem, GST_D3D11_MEMORY_TRANSFER_NEED_UPLOAD); @@ -492,9 +485,7 @@ unmap_cpu_access_data (GstD3D11Memory * dmem) if (priv->type == GST_D3D11_MEMORY_TYPE_STAGING) staging = (ID3D11Resource *) priv->texture; - gst_d3d11_device_lock (dmem->device); ID3D11DeviceContext_Unmap (device_context, staging, 0); - gst_d3d11_device_unlock (dmem->device); } static void @@ -693,7 +684,6 @@ calculate_mem_size (GstD3D11Device * device, ID3D11Texture2D * texture, ID3D11DeviceContext *device_context = gst_d3d11_device_get_device_context_handle (device); - gst_d3d11_device_lock (device); hr = ID3D11DeviceContext_Map (device_context, (ID3D11Resource *) texture, 0, map_type, 0, &map); @@ -707,7 +697,6 @@ calculate_mem_size (GstD3D11Device * device, ID3D11Texture2D * texture, desc->Width, desc->Height, map.RowPitch, offset, stride, size); ID3D11DeviceContext_Unmap (device_context, (ID3D11Resource *) texture, 0); - gst_d3d11_device_unlock (device); return ret; } diff --git a/gst-libs/gst/d3d11/meson.build b/gst-libs/gst/d3d11/meson.build index b699082d5..b0b2ae9cf 100644 --- a/gst-libs/gst/d3d11/meson.build +++ b/gst-libs/gst/d3d11/meson.build @@ -72,7 +72,7 @@ foreach d3d11_h: d3d11_headers endif endforeach -have_d3d11 = d3d11_lib.found() and dxgi_lib.found() and have_d3d11_header and have_dxgi_header +have_d3d11 = d3d11_lib.found() and dxgi_lib.found() and have_d3d11_header and have_dxgi_header and cc.has_header('d3d10.h') if not have_d3d11 if d3d11_option.enabled() error('The d3d11 was enabled explicitly, but required dependencies were not found.') -- cgit v1.2.1