d3d12memory: Implement NT handle caching and custom user data support

Same as the d3d11 memory implementation.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6256>
This commit is contained in:
Seungha Yang 2024-03-05 22:49:05 +09:00
parent 04077ce906
commit 63ef405131
4 changed files with 102 additions and 1 deletions

View file

@ -32,6 +32,8 @@
#include <atomic>
#include <queue>
#include <vector>
#include <map>
#include <memory>
/* *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<ID3D12Resource> resource;
@ -219,6 +242,8 @@ struct _GstD3D12MemoryPrivate
D3D12_RESOURCE_DESC desc;
HANDLE event_handle = nullptr;
HANDLE nt_handle = nullptr;
std::map<gint64, std::unique_ptr<GstD3D12MemoryTokenData>> 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);

View file

@ -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
{

View file

@ -23,6 +23,7 @@
#include "gstd3d12.h"
#include <mutex>
#include <atomic>
/* *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<gint64> user_token { 0 };
/* *INDENT-ON* */
return user_token.fetch_add (1);
}
gboolean

View file

@ -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,