mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 05:06:17 +00:00
d3d12memory: Add support for d3d11 texture caching
Would be useful for various D3D11 interop use cases Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6499>
This commit is contained in:
parent
e023546162
commit
ce34e63605
4 changed files with 94 additions and 14 deletions
|
@ -38,6 +38,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <dxgi1_6.h>
|
#include <dxgi1_6.h>
|
||||||
|
#include <d3d11.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <d3d11_1.h>
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
using namespace Microsoft::WRL;
|
using namespace Microsoft::WRL;
|
||||||
|
@ -316,6 +318,12 @@ struct GstD3D12MemoryTokenData
|
||||||
GDestroyNotify notify;
|
GDestroyNotify notify;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct D3D11Interop
|
||||||
|
{
|
||||||
|
ComPtr<ID3D11Device> device11;
|
||||||
|
ComPtr<ID3D11Texture2D> texture11;
|
||||||
|
};
|
||||||
|
|
||||||
struct _GstD3D12MemoryPrivate
|
struct _GstD3D12MemoryPrivate
|
||||||
{
|
{
|
||||||
_GstD3D12MemoryPrivate ()
|
_GstD3D12MemoryPrivate ()
|
||||||
|
@ -346,6 +354,7 @@ struct _GstD3D12MemoryPrivate
|
||||||
HANDLE event_handle = nullptr;
|
HANDLE event_handle = nullptr;
|
||||||
HANDLE nt_handle = nullptr;
|
HANDLE nt_handle = nullptr;
|
||||||
std::map<gint64, std::unique_ptr<GstD3D12MemoryTokenData>> token_map;
|
std::map<gint64, std::unique_ptr<GstD3D12MemoryTokenData>> token_map;
|
||||||
|
std::vector<std::shared_ptr<D3D11Interop>> shared_texture11;
|
||||||
|
|
||||||
/* Queryied via ID3D12Device::GetCopyableFootprints */
|
/* Queryied via ID3D12Device::GetCopyableFootprints */
|
||||||
D3D12_PLACED_SUBRESOURCE_FOOTPRINT layout[GST_VIDEO_MAX_PLANES];
|
D3D12_PLACED_SUBRESOURCE_FOOTPRINT layout[GST_VIDEO_MAX_PLANES];
|
||||||
|
@ -866,6 +875,28 @@ gst_d3d12_memory_get_render_target_view_heap (GstD3D12Memory * mem)
|
||||||
return priv->rtv_heap.Get ();
|
return priv->rtv_heap.Get ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_d3d12_memory_get_nt_handle_unlocked (GstD3D12Memory * mem, HANDLE * handle)
|
||||||
|
{
|
||||||
|
auto priv = mem->priv;
|
||||||
|
|
||||||
|
*handle = nullptr;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_d3d12_memory_get_nt_handle:
|
* gst_d3d12_memory_get_nt_handle:
|
||||||
* @mem: a #GstD3D12Memory
|
* @mem: a #GstD3D12Memory
|
||||||
|
@ -884,22 +915,9 @@ gst_d3d12_memory_get_nt_handle (GstD3D12Memory * mem, HANDLE * handle)
|
||||||
{
|
{
|
||||||
auto priv = mem->priv;
|
auto priv = mem->priv;
|
||||||
|
|
||||||
*handle = nullptr;
|
|
||||||
|
|
||||||
std::lock_guard < std::mutex > lk (priv->lock);
|
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);
|
return gst_d3d12_memory_get_nt_handle_unlocked (mem, handle);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -976,6 +994,60 @@ gst_d3d12_memory_set_external_fence (GstD3D12Memory * mem, ID3D12Fence * fence,
|
||||||
gst_d3d12_memory_set_external_fence_unlocked (mem, fence, fence_val);
|
gst_d3d12_memory_set_external_fence_unlocked (mem, fence, fence_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_d3d12_memory_get_d3d11_texture:
|
||||||
|
* @mem: a #GstD3D12Memory
|
||||||
|
* @device11: a ID3D11Device
|
||||||
|
*
|
||||||
|
* Opens ID3D11Texture2D texture from ID3D12Resource
|
||||||
|
*
|
||||||
|
* Returns: (transfer none) (nullable): ID3D11Texture2D handle or %NULL
|
||||||
|
* if resource sharing is not supported
|
||||||
|
*
|
||||||
|
* Since: 1.26
|
||||||
|
*/
|
||||||
|
ID3D11Texture2D *
|
||||||
|
gst_d3d12_memory_get_d3d11_texture (GstD3D12Memory * mem,
|
||||||
|
ID3D11Device * device11)
|
||||||
|
{
|
||||||
|
auto priv = mem->priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (mem, nullptr);
|
||||||
|
g_return_val_if_fail (device11, nullptr);
|
||||||
|
|
||||||
|
std::lock_guard < std::mutex > lk (priv->lock);
|
||||||
|
auto it = std::find_if (priv->shared_texture11.begin (),
|
||||||
|
priv->shared_texture11.end (),[&](const auto & shared)->bool {
|
||||||
|
return shared->device11.Get () == device11;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (it != priv->shared_texture11.end ())
|
||||||
|
return (*it)->texture11.Get ();
|
||||||
|
|
||||||
|
HANDLE shared_handle;
|
||||||
|
if (!gst_d3d12_memory_get_nt_handle_unlocked (mem, &shared_handle))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
ComPtr < ID3D11Device1 > device11_1;
|
||||||
|
auto hr = device11->QueryInterface (IID_PPV_ARGS (&device11_1));
|
||||||
|
if (FAILED (hr))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
ComPtr < ID3D11Texture2D > texture11;
|
||||||
|
hr = device11_1->OpenSharedResource1 (shared_handle,
|
||||||
|
IID_PPV_ARGS (&texture11));
|
||||||
|
if (FAILED (hr))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
auto storage = std::make_shared < D3D11Interop > ();
|
||||||
|
storage->device11 = device11;
|
||||||
|
storage->texture11 = texture11;
|
||||||
|
priv->shared_texture11.push_back (std::move (storage));
|
||||||
|
|
||||||
|
return texture11.Get ();
|
||||||
|
}
|
||||||
|
|
||||||
/* GstD3D12Allocator */
|
/* GstD3D12Allocator */
|
||||||
#define gst_d3d12_allocator_parent_class alloc_parent_class
|
#define gst_d3d12_allocator_parent_class alloc_parent_class
|
||||||
G_DEFINE_TYPE (GstD3D12Allocator, gst_d3d12_allocator, GST_TYPE_ALLOCATOR);
|
G_DEFINE_TYPE (GstD3D12Allocator, gst_d3d12_allocator, GST_TYPE_ALLOCATOR);
|
||||||
|
@ -1032,6 +1104,8 @@ gst_d3d12_allocator_free (GstAllocator * allocator, GstMemory * mem)
|
||||||
if (dmem->priv->notify)
|
if (dmem->priv->notify)
|
||||||
dmem->priv->notify (dmem->priv->user_data);
|
dmem->priv->notify (dmem->priv->user_data);
|
||||||
|
|
||||||
|
dmem->priv->shared_texture11.clear ();
|
||||||
|
|
||||||
delete dmem->priv;
|
delete dmem->priv;
|
||||||
|
|
||||||
gst_clear_object (&dmem->device);
|
gst_clear_object (&dmem->device);
|
||||||
|
|
|
@ -222,6 +222,10 @@ void gst_d3d12_memory_set_external_fence (GstD3D12Memory * mem,
|
||||||
ID3D12Fence * fence,
|
ID3D12Fence * fence,
|
||||||
guint64 fence_val);
|
guint64 fence_val);
|
||||||
|
|
||||||
|
GST_D3D12_API
|
||||||
|
ID3D11Texture2D * gst_d3d12_memory_get_d3d11_texture (GstD3D12Memory * mem,
|
||||||
|
ID3D11Device * device11);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstD3D12Allocator:
|
* GstD3D12Allocator:
|
||||||
*
|
*
|
||||||
|
|
|
@ -74,6 +74,7 @@ endif
|
||||||
|
|
||||||
sdk_headers = [
|
sdk_headers = [
|
||||||
'dxgi1_6.h',
|
'dxgi1_6.h',
|
||||||
|
'd3d11_1.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
have_d3d12_headers = true
|
have_d3d12_headers = true
|
||||||
|
|
Loading…
Reference in a new issue