d3d12device: Hold d3d11on12 device to be shared

d3d11on12 device seems to be occupying a bit of GPU memory
Hold the instance in GstD3D12Device so that it can be shared

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6697>
This commit is contained in:
Seungha Yang 2024-04-19 22:16:42 +09:00
parent 8e4fe98361
commit cd97275a19
5 changed files with 123 additions and 4 deletions

View file

@ -67,5 +67,26 @@
#define GST_D3D12_CALL_ONCE_END ) #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 */

View file

@ -52,5 +52,14 @@ void gst_d3d12_device_d3d12_debug (GstD3D12Device * device,
const gchar * function, const gchar * function,
gint line); 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 G_END_DECLS

View file

@ -25,6 +25,7 @@
#include "gstd3d12-private.h" #include "gstd3d12-private.h"
#include "gstd3d12commandlistpool.h" #include "gstd3d12commandlistpool.h"
#include <directx/d3dx12.h> #include <directx/d3dx12.h>
#include <d3d11on12.h>
#include <wrl.h> #include <wrl.h>
#include <vector> #include <vector>
#include <string.h> #include <string.h>
@ -39,6 +40,7 @@
#include <queue> #include <queue>
#include <unordered_map> #include <unordered_map>
#include <thread> #include <thread>
#include <gmodule.h>
GST_DEBUG_CATEGORY_STATIC (gst_d3d12_sdk_debug); GST_DEBUG_CATEGORY_STATIC (gst_d3d12_sdk_debug);
@ -56,6 +58,30 @@ ensure_debug_category (void)
} }
#endif /* GST_DISABLE_GST_DEBUG */ #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 enum
{ {
PROP_0, PROP_0,
@ -146,8 +172,10 @@ struct DeviceInner
ComPtr<ID3D12Device> device; ComPtr<ID3D12Device> device;
ComPtr<IDXGIAdapter1> adapter; ComPtr<IDXGIAdapter1> adapter;
ComPtr<IDXGIFactory2> factory; ComPtr<IDXGIFactory2> factory;
ComPtr<ID3D11On12Device> device11on12;
std::unordered_map<GstVideoFormat, GstD3D12Format> format_table; std::unordered_map<GstVideoFormat, GstD3D12Format> format_table;
std::recursive_mutex extern_lock; std::recursive_mutex extern_lock;
std::recursive_mutex device11on12_lock;
std::mutex lock; std::mutex lock;
ComPtr<ID3D12InfoQueue> info_queue; ComPtr<ID3D12InfoQueue> info_queue;
@ -1356,3 +1384,64 @@ gst_d3d12_device_is_equal (GstD3D12Device * device1, GstD3D12Device * device2)
return FALSE; 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 ();
}

View file

@ -77,6 +77,7 @@ endif
sdk_headers = [ sdk_headers = [
'dxgi1_6.h', 'dxgi1_6.h',
'd3d11_1.h', 'd3d11_1.h',
'd3d11on12.h',
] ]
have_d3d12_headers = true have_d3d12_headers = true
@ -125,12 +126,12 @@ endif
pkg_name = 'gstreamer-d3d12-' + api_version pkg_name = 'gstreamer-d3d12-' + api_version
gstd3d12 = library('gstd3d12-' + api_version, gstd3d12 = library('gstd3d12-' + api_version,
d3d12_sources + hlsl_precompiled, d3d12_sources,
c_args : gst_plugins_bad_args + extra_args, c_args : gst_plugins_bad_args + extra_args,
cpp_args: gst_plugins_bad_args + extra_args, cpp_args: gst_plugins_bad_args + extra_args,
include_directories : [configinc, libsinc], include_directories : [configinc, libsinc],
dependencies : [gstbase_dep, gstvideo_dep, gstd3dshader_dep, d3d12_lib, 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, version : libversion,
install : true, install : true,
) )

View file

@ -127,7 +127,6 @@ endif
d3d12_headers = [ d3d12_headers = [
'd3d11.h', 'd3d11.h',
'd3d11on12.h',
'd2d1.h', 'd2d1.h',
] ]