From 63ef405131405131db3cebf2fa4004372be14da6 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Tue, 5 Mar 2024 22:49:05 +0900 Subject: [PATCH] d3d12memory: Implement NT handle caching and custom user data support Same as the d3d11 memory implementation. Part-of: --- .../sys/d3d12/gstd3d12memory.cpp | 81 ++++++++++++++++++- .../sys/d3d12/gstd3d12memory.h | 10 +++ .../sys/d3d12/gstd3d12utils.cpp | 10 +++ .../gst-plugins-bad/sys/d3d12/gstd3d12utils.h | 2 + 4 files changed, 102 insertions(+), 1 deletion(-) diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12memory.cpp b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12memory.cpp index ad9c4efced..6b5414b669 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12memory.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12memory.cpp @@ -32,6 +32,8 @@ #include #include #include +#include +#include /* *INDENT-OFF* */ using namespace Microsoft::WRL; @@ -198,14 +200,35 @@ gst_d3d12_allocation_params_set_array_size (GstD3D12AllocationParams * params, return TRUE; } - /* *INDENT-OFF* */ +struct GstD3D12MemoryTokenData +{ + GstD3D12MemoryTokenData (gpointer data, GDestroyNotify notify_func) + : user_data (data), notify (notify_func) + { + } + + ~GstD3D12MemoryTokenData () + { + if (notify) + notify (user_data); + } + + gpointer user_data; + GDestroyNotify notify; +}; + struct _GstD3D12MemoryPrivate { ~_GstD3D12MemoryPrivate () { if (event_handle) CloseHandle (event_handle); + + if (nt_handle) + CloseHandle (nt_handle); + + token_map.clear (); } ComPtr resource; @@ -219,6 +242,8 @@ struct _GstD3D12MemoryPrivate D3D12_RESOURCE_DESC desc; HANDLE event_handle = nullptr; + HANDLE nt_handle = nullptr; + std::map> token_map; /* Queryied via ID3D12Device::GetCopyableFootprints */ D3D12_PLACED_SUBRESOURCE_FOOTPRINT layout[GST_VIDEO_MAX_PLANES]; @@ -628,6 +653,60 @@ gst_d3d12_memory_get_render_target_view_heap (GstD3D12Memory * mem, return TRUE; } +gboolean +gst_d3d12_memory_get_nt_handle (GstD3D12Memory * mem, HANDLE * handle) +{ + auto priv = mem->priv; + + *handle = nullptr; + + std::lock_guard < std::mutex > lk (priv->lock); + if (priv->nt_handle) { + *handle = priv->nt_handle; + return TRUE; + } + + auto device = gst_d3d12_device_get_device_handle (mem->device); + auto hr = device->CreateSharedHandle (priv->resource.Get (), nullptr, + GENERIC_ALL, nullptr, &priv->nt_handle); + if (!gst_d3d12_result (hr, mem->device)) + return FALSE; + + *handle = priv->nt_handle; + return TRUE; +} + +void +gst_d3d12_memory_set_token_data (GstD3D12Memory * mem, gint64 token, + gpointer data, GDestroyNotify notify) +{ + auto priv = mem->priv; + + std::lock_guard < std::mutex > lk (priv->lock); + auto old_token = priv->token_map.find (token); + if (old_token != priv->token_map.end ()) + priv->token_map.erase (old_token); + + if (data) { + priv->token_map[token] = std::unique_ptr < GstD3D12MemoryTokenData > + (new GstD3D12MemoryTokenData (data, notify)); + } +} + +gpointer +gst_d3d12_memory_get_token_data (GstD3D12Memory * mem, gint64 token) +{ + auto priv = mem->priv; + gpointer ret = nullptr; + + std::lock_guard < std::mutex > lk (priv->lock); + auto old_token = priv->token_map.find (token); + if (old_token != priv->token_map.end ()) + ret = old_token->second->user_data; + + return ret; +} + /* GstD3D12Allocator */ #define gst_d3d12_allocator_parent_class alloc_parent_class G_DEFINE_TYPE (GstD3D12Allocator, gst_d3d12_allocator, GST_TYPE_ALLOCATOR); diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12memory.h b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12memory.h index 1de368410e..687ce2fca7 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12memory.h +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12memory.h @@ -149,6 +149,16 @@ gboolean gst_d3d12_memory_get_shader_resource_view_heap (GstD3D12Memory gboolean gst_d3d12_memory_get_render_target_view_heap (GstD3D12Memory * mem, ID3D12DescriptorHeap ** heap); +gboolean gst_d3d12_memory_get_nt_handle (GstD3D12Memory * mem, + HANDLE * handle); + +void gst_d3d12_memory_set_token_data (GstD3D12Memory * mem, + gint64 token, + gpointer data, + GDestroyNotify notify); + +gpointer gst_d3d12_memory_get_token_data (GstD3D12Memory * mem, + gint64 token); struct _GstD3D12Allocator { diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12utils.cpp b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12utils.cpp index f0a030c4b9..7936ee43f0 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12utils.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12utils.cpp @@ -23,6 +23,7 @@ #include "gstd3d12.h" #include +#include /* *INDENT-OFF* */ static std::recursive_mutex context_lock_; @@ -398,7 +399,16 @@ gst_d3d12_context_new (GstD3D12Device * device) context_set_d3d12_device (context, device); return context; +} +gint64 +gst_d3d12_create_user_token (void) +{ + /* *INDENT-OFF* */ + static std::atomic user_token { 0 }; + /* *INDENT-ON* */ + + return user_token.fetch_add (1); } gboolean diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12utils.h b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12utils.h index a59a82a59f..3ee9f8edbf 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12utils.h +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12utils.h @@ -50,6 +50,8 @@ gint64 gst_d3d12_luid_to_int64 (const LUID * luid); GstContext * gst_d3d12_context_new (GstD3D12Device * device); +gint64 gst_d3d12_create_user_token (void); + gboolean _gst_d3d12_result (HRESULT hr, GstD3D12Device * device, GstDebugCategory * cat,