diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12-private.h b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12-private.h index ebc090fea1..fa78c20fb9 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12-private.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12-private.h @@ -67,5 +67,26 @@ #define GST_D3D12_CALL_ONCE_END ) -#endif /* __cplusplus */ +class GstD3D12Device11on12LockGuard +{ +public: + explicit GstD3D12Device11on12LockGuard(GstD3D12Device * device) : device_ (device) + { + if (device_) + gst_d3d12_device_11on12_lock (device_); + } + ~GstD3D12Device11on12LockGuard() + { + if (device_) + gst_d3d12_device_11on12_unlock (device_); + } + + GstD3D12Device11on12LockGuard(const GstD3D12Device11on12LockGuard&) = delete; + GstD3D12Device11on12LockGuard& operator=(const GstD3D12Device11on12LockGuard&) = delete; + +private: + GstD3D12Device *device_; +}; + +#endif /* __cplusplus */ diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12device-private.h b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12device-private.h index 5ccc54531b..5257446c83 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12device-private.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12device-private.h @@ -52,5 +52,14 @@ void gst_d3d12_device_d3d12_debug (GstD3D12Device * device, const gchar * function, gint line); +GST_D3D12_API +IUnknown * gst_d3d12_device_get_11on12_handle (GstD3D12Device * device); + +GST_D3D12_API +void gst_d3d12_device_11on12_lock (GstD3D12Device * device); + +GST_D3D12_API +void gst_d3d12_device_11on12_unlock (GstD3D12Device * device); + G_END_DECLS diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12device.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12device.cpp index c1d83c56ff..e7bfdba731 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12device.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12device.cpp @@ -25,6 +25,7 @@ #include "gstd3d12-private.h" #include "gstd3d12commandlistpool.h" #include +#include #include #include #include @@ -39,6 +40,7 @@ #include #include #include +#include GST_DEBUG_CATEGORY_STATIC (gst_d3d12_sdk_debug); @@ -56,6 +58,30 @@ ensure_debug_category (void) } #endif /* GST_DISABLE_GST_DEBUG */ +static PFN_D3D11ON12_CREATE_DEVICE GstD3D11On12CreateDevice = nullptr; + +static gboolean +load_d3d11on12_symbol (void) +{ + static gboolean ret = FALSE; + static GModule *d3d11_lib_module = nullptr; + GST_D3D12_CALL_ONCE_BEGIN { + d3d11_lib_module = g_module_open ("d3d11.dll", G_MODULE_BIND_LAZY); + if (!d3d11_lib_module) + return; + + if (!g_module_symbol (d3d11_lib_module, "D3D11On12CreateDevice", + (gpointer *) & GstD3D11On12CreateDevice)) { + return; + } + + ret = TRUE; + } + GST_D3D12_CALL_ONCE_END; + + return ret; +} + enum { PROP_0, @@ -146,8 +172,10 @@ struct DeviceInner ComPtr device; ComPtr adapter; ComPtr factory; + ComPtr device11on12; std::unordered_map format_table; std::recursive_mutex extern_lock; + std::recursive_mutex device11on12_lock; std::mutex lock; ComPtr info_queue; @@ -1356,3 +1384,64 @@ gst_d3d12_device_is_equal (GstD3D12Device * device1, GstD3D12Device * device2) return FALSE; } + +IUnknown * +gst_d3d12_device_get_11on12_handle (GstD3D12Device * device) +{ + g_return_val_if_fail (GST_IS_D3D12_DEVICE (device), nullptr); + + auto priv = device->priv->inner; + std::lock_guard < std::mutex > lk (priv->lock); + + if (!priv->device11on12) { + if (!load_d3d11on12_symbol ()) { + GST_WARNING_OBJECT (device, "D3D11On12CreateDevice symbol was not found"); + return nullptr; + } + + static const D3D_FEATURE_LEVEL feature_levels[] = { + D3D_FEATURE_LEVEL_12_1, + D3D_FEATURE_LEVEL_12_0, + D3D_FEATURE_LEVEL_11_1, + D3D_FEATURE_LEVEL_11_0, + }; + + IUnknown *cq[] = + { gst_d3d12_command_queue_get_handle (priv->direct_queue) }; + ComPtr < ID3D11Device > device11; + auto hr = GstD3D11On12CreateDevice (priv->device.Get (), + D3D11_CREATE_DEVICE_BGRA_SUPPORT, feature_levels, + G_N_ELEMENTS (feature_levels), cq, 1, 0, &device11, nullptr, nullptr); + if (FAILED (hr)) { + GST_WARNING_OBJECT (device, "Couldn't create 11on12 device, hr: 0x%x", + (guint) hr); + return nullptr; + } + + hr = device11.As (&priv->device11on12); + if (FAILED (hr)) { + GST_ERROR_OBJECT (device, "Couldn't get 11on12 interface"); + return nullptr; + } + } + + return priv->device11on12.Get (); +} + +void +gst_d3d12_device_11on12_lock (GstD3D12Device * device) +{ + g_return_if_fail (GST_IS_D3D12_DEVICE (device)); + + auto priv = device->priv->inner; + priv->device11on12_lock.lock (); +} + +void +gst_d3d12_device_11on12_unlock (GstD3D12Device * device) +{ + g_return_if_fail (GST_IS_D3D12_DEVICE (device)); + + auto priv = device->priv->inner; + priv->device11on12_lock.unlock (); +} diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/meson.build b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/meson.build index daf65d75a5..3d8cd7c3de 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/meson.build +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/meson.build @@ -77,6 +77,7 @@ endif sdk_headers = [ 'dxgi1_6.h', 'd3d11_1.h', + 'd3d11on12.h', ] have_d3d12_headers = true @@ -125,12 +126,12 @@ endif pkg_name = 'gstreamer-d3d12-' + api_version gstd3d12 = library('gstd3d12-' + api_version, - d3d12_sources + hlsl_precompiled, + d3d12_sources, c_args : gst_plugins_bad_args + extra_args, cpp_args: gst_plugins_bad_args + extra_args, include_directories : [configinc, libsinc], dependencies : [gstbase_dep, gstvideo_dep, gstd3dshader_dep, d3d12_lib, - dxgi_lib, dx_headers_dep] + extra_deps, + dxgi_lib, dx_headers_dep, gmodule_dep] + extra_deps, version : libversion, install : true, ) diff --git a/subprojects/gst-plugins-bad/sys/d3d12/meson.build b/subprojects/gst-plugins-bad/sys/d3d12/meson.build index 55e878e8d7..8edbd577bc 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/meson.build +++ b/subprojects/gst-plugins-bad/sys/d3d12/meson.build @@ -127,7 +127,6 @@ endif d3d12_headers = [ 'd3d11.h', - 'd3d11on12.h', 'd2d1.h', ]