diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12commandallocatorpool.cpp b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12commandallocatorpool.cpp new file mode 100644 index 0000000000..f405981161 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12commandallocatorpool.cpp @@ -0,0 +1,251 @@ +/* GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstd3d12commandallocatorpool.h" +#include "gstd3d12device.h" +#include +#include +#include + +GST_DEBUG_CATEGORY_STATIC (gst_d3d12_command_allocator_pool_debug); +#define GST_CAT_DEFAULT gst_d3d12_command_allocator_pool_debug + +/* *INDENT-OFF* */ +using namespace Microsoft::WRL; + +struct _GstD3D12CommandAllocator : public GstMiniObject +{ + GstD3D12CommandAllocatorPool *pool = nullptr; + D3D12_COMMAND_LIST_TYPE type; + ComPtr < ID3D12CommandAllocator > ca; +}; + +struct GstD3D12CommandAllocatorPoolPrivate +{ + ~GstD3D12CommandAllocatorPoolPrivate () + { + while (!cmd_pool.empty ()) { + auto cmd = cmd_pool.front (); + cmd_pool.pop (); + gst_mini_object_unref (cmd); + } + } + + ComPtr device; + + std::mutex lock; + std::queuecmd_pool; + D3D12_COMMAND_LIST_TYPE cmd_type; +}; +/* *INDENT-ON* */ + +struct _GstD3D12CommandAllocatorPool +{ + GstObject parent; + + GstD3D12CommandAllocatorPoolPrivate *priv; +}; + +GST_DEFINE_MINI_OBJECT_TYPE (GstD3D12CommandAllocator, + gst_d3d12_command_allocator); + +static void gst_d3d12_command_allocator_pool_finalize (GObject * object); + +#define gst_d3d12_command_allocator_pool_parent_class parent_class +G_DEFINE_TYPE (GstD3D12CommandAllocatorPool, + gst_d3d12_command_allocator_pool, GST_TYPE_OBJECT); + +static void +gst_d3d12_command_allocator_pool_class_init (GstD3D12CommandAllocatorPoolClass * + klass) +{ + auto object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gst_d3d12_command_allocator_pool_finalize; + + GST_DEBUG_CATEGORY_INIT (gst_d3d12_command_allocator_pool_debug, + "d3d12commandallocatorpool", 0, "d3d12commandallocatorpool"); +} + +static void +gst_d3d12_command_allocator_pool_init (GstD3D12CommandAllocatorPool * self) +{ + self->priv = new GstD3D12CommandAllocatorPoolPrivate (); +} + +static void +gst_d3d12_command_allocator_pool_finalize (GObject * object) +{ + auto self = GST_D3D12_COMMAND_ALLOCATOR_POOL (object); + + delete self->priv; + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +GstD3D12CommandAllocatorPool * +gst_d3d12_command_allocator_pool_new (GstD3D12Device * device, + D3D12_COMMAND_LIST_TYPE type) +{ + g_return_val_if_fail (GST_IS_D3D12_DEVICE (device), nullptr); + + auto self = (GstD3D12CommandAllocatorPool *) + g_object_new (GST_TYPE_D3D12_COMMAND_ALLOCATOR_POOL, nullptr); + gst_object_ref_sink (self); + + auto priv = self->priv; + priv->device = gst_d3d12_device_get_device_handle (device); + priv->cmd_type = type; + + return self; +} + +static void +gst_d3d12_command_allocator_pool_release (GstD3D12CommandAllocatorPool * pool, + GstD3D12CommandAllocator * cmd) +{ + auto priv = pool->priv; + { + std::lock_guard < std::mutex > lk (priv->lock); + cmd->dispose = nullptr; + cmd->pool = nullptr; + priv->cmd_pool.push (cmd); + } + + gst_object_unref (pool); +} + +static gboolean +gst_d3d12_command_allocator_dispose (GstD3D12CommandAllocator * cmd) +{ + if (!cmd->pool) + return TRUE; + + gst_mini_object_ref (cmd); + gst_d3d12_command_allocator_pool_release (cmd->pool, cmd); + + return FALSE; +} + +static void +gst_d3d12_command_allocator_free (GstD3D12CommandAllocator * cmd) +{ + delete cmd; +} + +static GstD3D12CommandAllocator * +gst_d3d12_command_allocator_new (ID3D12CommandAllocator * ca, + D3D12_COMMAND_LIST_TYPE type) +{ + auto cmd = new GstD3D12CommandAllocator (); + cmd->ca = ca; + cmd->type = type; + + gst_mini_object_init (cmd, 0, gst_d3d12_command_allocator_get_type (), + nullptr, nullptr, + (GstMiniObjectFreeFunction) gst_d3d12_command_allocator_free); + + return cmd; +} + +gboolean +gst_d3d12_command_allocator_pool_acquire (GstD3D12CommandAllocatorPool * pool, + GstD3D12CommandAllocator ** cmd) +{ + g_return_val_if_fail (GST_IS_D3D12_COMMAND_ALLOCATOR_POOL (pool), FALSE); + g_return_val_if_fail (cmd, FALSE); + + *cmd = nullptr; + + auto priv = pool->priv; + GstD3D12CommandAllocator *new_cmd = nullptr; + HRESULT hr; + + { + std::lock_guard < std::mutex > lk (priv->lock); + if (!priv->cmd_pool.empty ()) { + new_cmd = priv->cmd_pool.front (); + priv->cmd_pool.pop (); + } + } + + if (!new_cmd) { + ComPtr < ID3D12CommandAllocator > ca; + hr = priv->device->CreateCommandAllocator (priv->cmd_type, + IID_PPV_ARGS (&ca)); + if (FAILED (hr)) { + GST_ERROR_OBJECT (pool, "Couldn't create command allocator, hr: 0x%x", + (guint) hr); + return FALSE; + } + + new_cmd = gst_d3d12_command_allocator_new (ca.Get (), priv->cmd_type); + } + + new_cmd->pool = (GstD3D12CommandAllocatorPool *) gst_object_ref (pool); + new_cmd->dispose = + (GstMiniObjectDisposeFunction) gst_d3d12_command_allocator_dispose; + + *cmd = new_cmd; + + return TRUE; +} + +GstD3D12CommandAllocator * +gst_d3d12_command_allocator_ref (GstD3D12CommandAllocator * cmd) +{ + return (GstD3D12CommandAllocator *) gst_mini_object_ref (cmd); +} + +void +gst_d3d12_command_allocator_unref (GstD3D12CommandAllocator * cmd) +{ + gst_mini_object_unref (cmd); +} + +void +gst_clear_d3d12_command_allocator (GstD3D12CommandAllocator ** cmd) +{ + gst_clear_mini_object (cmd); +} + +D3D12_COMMAND_LIST_TYPE +gst_d3d12_command_allocator_get_command_type (GstD3D12CommandAllocator * cmd) +{ + g_return_val_if_fail (cmd, D3D12_COMMAND_LIST_TYPE_NONE); + + return cmd->type; +} + +gboolean +gst_d3d12_command_allocator_get_handle (GstD3D12CommandAllocator * cmd, + ID3D12CommandAllocator ** ca) +{ + g_return_val_if_fail (cmd, FALSE); + g_return_val_if_fail (ca, FALSE); + + *ca = cmd->ca.Get (); + (*ca)->AddRef (); + + return TRUE; +} diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12commandallocatorpool.h b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12commandallocatorpool.h new file mode 100644 index 0000000000..761b291147 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12commandallocatorpool.h @@ -0,0 +1,52 @@ +/* GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include +#include +#include "gstd3d12_fwd.h" + +G_BEGIN_DECLS + +#define GST_TYPE_D3D12_COMMAND_ALLOCATOR_POOL (gst_d3d12_command_allocator_pool_get_type()) +G_DECLARE_FINAL_TYPE (GstD3D12CommandAllocatorPool, + gst_d3d12_command_allocator_pool, GST, D3D12_COMMAND_ALLOCATOR_POOL, GstObject); + +typedef struct _GstD3D12CommandAllocator GstD3D12CommandAllocator; + +GstD3D12CommandAllocatorPool * gst_d3d12_command_allocator_pool_new (GstD3D12Device * device, + D3D12_COMMAND_LIST_TYPE type); + +gboolean gst_d3d12_command_allocator_pool_acquire (GstD3D12CommandAllocatorPool * pool, + GstD3D12CommandAllocator ** cmd); + +GstD3D12CommandAllocator * gst_d3d12_command_allocator_ref (GstD3D12CommandAllocator * cmd); + +void gst_d3d12_command_allocator_unref (GstD3D12CommandAllocator * cmd); + +void gst_clear_d3d12_command_allocator (GstD3D12CommandAllocator ** cmd); + +D3D12_COMMAND_LIST_TYPE gst_d3d12_command_allocator_get_command_type (GstD3D12CommandAllocator * cmd); + +gboolean gst_d3d12_command_allocator_get_handle (GstD3D12CommandAllocator * cmd, + ID3D12CommandAllocator ** ca); + +G_END_DECLS + diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12commandlistpool.cpp b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12commandlistpool.cpp new file mode 100644 index 0000000000..ad42917179 --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12commandlistpool.cpp @@ -0,0 +1,270 @@ +/* GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you cln redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstd3d12commandlistpool.h" +#include "gstd3d12device.h" +#include +#include +#include + +GST_DEBUG_CATEGORY_STATIC (gst_d3d12_command_list_pool_debug); +#define GST_CAT_DEFAULT gst_d3d12_command_list_pool_debug + +/* *INDENT-OFF* */ +using namespace Microsoft::WRL; + +struct _GstD3D12CommandList : public GstMiniObject +{ + GstD3D12CommandListPool *pool = nullptr; + D3D12_COMMAND_LIST_TYPE type; + ComPtr < ID3D12CommandList > cl; +}; + +struct GstD3D12CommandListPoolPrivate +{ + ~GstD3D12CommandListPoolPrivate () + { + while (!cmd_pool.empty ()) { + auto cmd = cmd_pool.front (); + cmd_pool.pop (); + gst_mini_object_unref (cmd); + } + } + + ComPtr device; + + std::mutex lock; + std::queuecmd_pool; + D3D12_COMMAND_LIST_TYPE cmd_type; +}; +/* *INDENT-ON* */ + +struct _GstD3D12CommandListPool +{ + GstObject parent; + + GstD3D12CommandListPoolPrivate *priv; +}; + +GST_DEFINE_MINI_OBJECT_TYPE (GstD3D12CommandList, gst_d3d12_command_list); + +static void gst_d3d12_command_list_pool_finalize (GObject * object); + +#define gst_d3d12_command_list_pool_parent_class parent_class +G_DEFINE_TYPE (GstD3D12CommandListPool, + gst_d3d12_command_list_pool, GST_TYPE_OBJECT); + +static void +gst_d3d12_command_list_pool_class_init (GstD3D12CommandListPoolClass * klass) +{ + auto object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gst_d3d12_command_list_pool_finalize; + + GST_DEBUG_CATEGORY_INIT (gst_d3d12_command_list_pool_debug, + "d3d12commandlistpool", 0, "d3d12commandlistpool"); +} + +static void +gst_d3d12_command_list_pool_init (GstD3D12CommandListPool * self) +{ + self->priv = new GstD3D12CommandListPoolPrivate (); +} + +static void +gst_d3d12_command_list_pool_finalize (GObject * object) +{ + auto self = GST_D3D12_COMMAND_LIST_POOL (object); + + delete self->priv; + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +GstD3D12CommandListPool * +gst_d3d12_command_list_pool_new (GstD3D12Device * device, + D3D12_COMMAND_LIST_TYPE type) +{ + g_return_val_if_fail (GST_IS_D3D12_DEVICE (device), nullptr); + + if (type != D3D12_COMMAND_LIST_TYPE_DIRECT && + type != D3D12_COMMAND_LIST_TYPE_COPY) { + GST_ERROR_OBJECT (device, "Not supported command list type"); + return nullptr; + } + + auto self = (GstD3D12CommandListPool *) + g_object_new (GST_TYPE_D3D12_COMMAND_LIST_POOL, nullptr); + gst_object_ref_sink (self); + + auto priv = self->priv; + priv->device = gst_d3d12_device_get_device_handle (device);; + priv->cmd_type = type; + + return self; +} + +static void +gst_d3d12_command_list_pool_release (GstD3D12CommandListPool * pool, + GstD3D12CommandList * cmd) +{ + auto priv = pool->priv; + { + std::lock_guard < std::mutex > lk (priv->lock); + cmd->dispose = nullptr; + cmd->pool = nullptr; + priv->cmd_pool.push (cmd); + } + + gst_object_unref (pool); +} + +static gboolean +gst_d3d12_command_list_dispose (GstD3D12CommandList * cmd) +{ + if (!cmd->pool) + return TRUE; + + gst_mini_object_ref (cmd); + gst_d3d12_command_list_pool_release (cmd->pool, cmd); + + return FALSE; +} + +static void +gst_d3d12_command_list_free (GstD3D12CommandList * cmd) +{ + delete cmd; +} + +static GstD3D12CommandList * +gst_d3d12_command_list_new (ID3D12CommandList * cl, + D3D12_COMMAND_LIST_TYPE type) +{ + auto cmd = new GstD3D12CommandList (); + cmd->cl = cl; + cmd->type = type; + + gst_mini_object_init (cmd, 0, gst_d3d12_command_list_get_type (), + nullptr, nullptr, + (GstMiniObjectFreeFunction) gst_d3d12_command_list_free); + + return cmd; +} + +gboolean +gst_d3d12_command_list_pool_acquire (GstD3D12CommandListPool * pool, + ID3D12CommandAllocator * ca, GstD3D12CommandList ** cmd) +{ + g_return_val_if_fail (GST_IS_D3D12_COMMAND_LIST_POOL (pool), FALSE); + g_return_val_if_fail (ca, FALSE); + g_return_val_if_fail (cmd, FALSE); + + *cmd = nullptr; + + auto priv = pool->priv; + GstD3D12CommandList *new_cmd = nullptr; + HRESULT hr; + + hr = ca->Reset (); + if (FAILED (hr)) { + GST_ERROR_OBJECT (pool, "Couldn't reset command allocator"); + return FALSE; + } + + { + std::lock_guard < std::mutex > lk (priv->lock); + if (!priv->cmd_pool.empty ()) { + new_cmd = priv->cmd_pool.front (); + priv->cmd_pool.pop (); + } + } + + ComPtr < ID3D12GraphicsCommandList > cl; + if (!new_cmd) { + hr = priv->device->CreateCommandList (0, priv->cmd_type, + ca, nullptr, IID_PPV_ARGS (&cl)); + if (FAILED (hr)) { + GST_ERROR_OBJECT (pool, "Couldn't create command list, hr: 0x%x", + (guint) hr); + return FALSE; + } + + new_cmd = gst_d3d12_command_list_new (cl.Get (), priv->cmd_type); + } else { + new_cmd->cl->QueryInterface (IID_PPV_ARGS (&cl)); + hr = cl->Reset (ca, nullptr); + if (FAILED (hr)) { + GST_ERROR_OBJECT (pool, "Couldn't reset command list"); + gst_mini_object_unref (new_cmd); + return false; + } + } + + new_cmd->pool = (GstD3D12CommandListPool *) gst_object_ref (pool); + new_cmd->dispose = + (GstMiniObjectDisposeFunction) gst_d3d12_command_list_dispose; + + *cmd = new_cmd; + + return TRUE; +} + +GstD3D12CommandList * +gst_d3d12_command_list_ref (GstD3D12CommandList * cmd) +{ + return (GstD3D12CommandList *) gst_mini_object_ref (cmd); +} + +void +gst_d3d12_command_list_unref (GstD3D12CommandList * cmd) +{ + gst_mini_object_unref (cmd); +} + +void +gst_clear_d3d12_command_list (GstD3D12CommandList ** cmd) +{ + gst_clear_mini_object (cmd); +} + +D3D12_COMMAND_LIST_TYPE +gst_d3d12_command_list_get_command_type (GstD3D12CommandList * cmd) +{ + g_return_val_if_fail (cmd, D3D12_COMMAND_LIST_TYPE_NONE); + + return cmd->type; +} + +gboolean +gst_d3d12_command_list_get_handle (GstD3D12CommandList * cmd, + ID3D12CommandList ** cl) +{ + g_return_val_if_fail (cmd, FALSE); + g_return_val_if_fail (cl, FALSE); + + *cl = cmd->cl.Get (); + (*cl)->AddRef (); + + return TRUE; +} diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12commandlistpool.h b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12commandlistpool.h new file mode 100644 index 0000000000..b2928eb0ea --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12commandlistpool.h @@ -0,0 +1,53 @@ +/* GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include +#include +#include "gstd3d12_fwd.h" + +G_BEGIN_DECLS + +#define GST_TYPE_D3D12_COMMAND_LIST_POOL (gst_d3d12_command_list_pool_get_type()) +G_DECLARE_FINAL_TYPE (GstD3D12CommandListPool, + gst_d3d12_command_list_pool, GST, D3D12_COMMAND_LIST_POOL, GstObject); + +typedef struct _GstD3D12CommandList GstD3D12CommandList; + +GstD3D12CommandListPool * gst_d3d12_command_list_pool_new (GstD3D12Device * device, + D3D12_COMMAND_LIST_TYPE type); + +gboolean gst_d3d12_command_list_pool_acquire (GstD3D12CommandListPool * pool, + ID3D12CommandAllocator * ca, + GstD3D12CommandList ** cmd); + +GstD3D12CommandList * gst_d3d12_command_list_ref (GstD3D12CommandList * cmd); + +void gst_d3d12_command_list_unref (GstD3D12CommandList * cmd); + +void gst_clear_d3d12_command_list (GstD3D12CommandList ** cmd); + +D3D12_COMMAND_LIST_TYPE gst_d3d12_command_list_get_command_type (GstD3D12CommandList * cmd); + +gboolean gst_d3d12_command_list_get_handle (GstD3D12CommandList * cmd, + ID3D12CommandList ** cl); + +G_END_DECLS + diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12descriptorpool.cpp b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12descriptorpool.cpp new file mode 100644 index 0000000000..211cc93a1b --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12descriptorpool.cpp @@ -0,0 +1,238 @@ +/* GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you cln redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstd3d12descriptorpool.h" +#include "gstd3d12device.h" +#include +#include +#include + +GST_DEBUG_CATEGORY_STATIC (gst_d3d12_descriptor_pool_debug); +#define GST_CAT_DEFAULT gst_d3d12_descriptor_pool_debug + +/* *INDENT-OFF* */ +using namespace Microsoft::WRL; + +struct _GstD3D12Descriptor : public GstMiniObject +{ + GstD3D12DescriptorPool *pool = nullptr; + ComPtr < ID3D12DescriptorHeap > heap; +}; + +struct GstD3D12DescriptorPoolPrivate +{ + ~GstD3D12DescriptorPoolPrivate () + { + while (!heap_pool.empty ()) { + auto desc = heap_pool.front (); + heap_pool.pop (); + gst_mini_object_unref (desc); + } + } + + ComPtr device; + + std::mutex lock; + std::queueheap_pool; + D3D12_DESCRIPTOR_HEAP_DESC heap_desc; +}; +/* *INDENT-ON* */ + +struct _GstD3D12DescriptorPool +{ + GstObject parent; + + GstD3D12DescriptorPoolPrivate *priv; +}; + +GST_DEFINE_MINI_OBJECT_TYPE (GstD3D12Descriptor, gst_d3d12_descriptor); + +static void gst_d3d12_descriptor_pool_finalize (GObject * object); + +#define gst_d3d12_descriptor_pool_parent_class parent_class +G_DEFINE_TYPE (GstD3D12DescriptorPool, + gst_d3d12_descriptor_pool, GST_TYPE_OBJECT); + +static void +gst_d3d12_descriptor_pool_class_init (GstD3D12DescriptorPoolClass * klass) +{ + auto object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gst_d3d12_descriptor_pool_finalize; + + GST_DEBUG_CATEGORY_INIT (gst_d3d12_descriptor_pool_debug, + "d3d12descriptorpool", 0, "d3d12descriptorpool"); +} + +static void +gst_d3d12_descriptor_pool_init (GstD3D12DescriptorPool * self) +{ + self->priv = new GstD3D12DescriptorPoolPrivate (); +} + +static void +gst_d3d12_descriptor_pool_finalize (GObject * object) +{ + auto self = GST_D3D12_DESCRIPTOR_POOL (object); + + delete self->priv; + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +GstD3D12DescriptorPool * +gst_d3d12_descriptor_pool_new (GstD3D12Device * device, + const D3D12_DESCRIPTOR_HEAP_DESC * desc) +{ + g_return_val_if_fail (GST_IS_D3D12_DEVICE (device), nullptr); + g_return_val_if_fail (desc, nullptr); + + auto self = (GstD3D12DescriptorPool *) + g_object_new (GST_TYPE_D3D12_DESCRIPTOR_POOL, nullptr); + gst_object_ref_sink (self); + + auto priv = self->priv; + priv->device = gst_d3d12_device_get_device_handle (device); + priv->heap_desc = *desc; + + return self; +} + +static void +gst_d3d12_descriptor_pool_release (GstD3D12DescriptorPool * pool, + GstD3D12Descriptor * desc) +{ + auto priv = pool->priv; + { + std::lock_guard < std::mutex > lk (priv->lock); + desc->dispose = nullptr; + desc->pool = nullptr; + priv->heap_pool.push (desc); + } + + gst_object_unref (pool); +} + +static gboolean +gst_d3d12_descriptor_dispose (GstD3D12Descriptor * desc) +{ + if (!desc->pool) + return TRUE; + + gst_mini_object_ref (desc); + gst_d3d12_descriptor_pool_release (desc->pool, desc); + + return FALSE; +} + +static void +gst_d3d12_descriptor_free (GstD3D12Descriptor * desc) +{ + delete desc; +} + +static GstD3D12Descriptor * +gst_d3d12_descriptor_new (ID3D12DescriptorHeap * heap) +{ + auto desc = new GstD3D12Descriptor (); + desc->heap = heap; + + gst_mini_object_init (desc, 0, gst_d3d12_descriptor_get_type (), + nullptr, nullptr, (GstMiniObjectFreeFunction) gst_d3d12_descriptor_free); + + return desc; +} + +gboolean +gst_d3d12_descriptor_pool_acquire (GstD3D12DescriptorPool * pool, + GstD3D12Descriptor ** desc) +{ + g_return_val_if_fail (GST_IS_D3D12_DESCRIPTOR_POOL (pool), FALSE); + g_return_val_if_fail (desc, FALSE); + + *desc = nullptr; + + auto priv = pool->priv; + GstD3D12Descriptor *new_desc = nullptr; + HRESULT hr; + + { + std::lock_guard < std::mutex > lk (priv->lock); + if (!priv->heap_pool.empty ()) { + new_desc = priv->heap_pool.front (); + priv->heap_pool.pop (); + } + } + + if (!new_desc) { + ComPtr < ID3D12DescriptorHeap > heap; + hr = priv->device->CreateDescriptorHeap (&priv->heap_desc, + IID_PPV_ARGS (&heap)); + if (FAILED (hr)) { + GST_ERROR_OBJECT (pool, "Couldn't create descriptor heap, hr: 0x%x", + (guint) hr); + return FALSE; + } + + new_desc = gst_d3d12_descriptor_new (heap.Get ()); + } + + new_desc->pool = (GstD3D12DescriptorPool *) gst_object_ref (pool); + new_desc->dispose = + (GstMiniObjectDisposeFunction) gst_d3d12_descriptor_dispose; + + *desc = new_desc; + + return TRUE; +} + +GstD3D12Descriptor * +gst_d3d12_descriptor_ref (GstD3D12Descriptor * desc) +{ + return (GstD3D12Descriptor *) gst_mini_object_ref (desc); +} + +void +gst_d3d12_descriptor_unref (GstD3D12Descriptor * desc) +{ + gst_mini_object_unref (desc); +} + +void +gst_clear_d3d12_descriptor (GstD3D12Descriptor ** desc) +{ + gst_clear_mini_object (desc); +} + +gboolean +gst_d3d12_descriptor_get_handle (GstD3D12Descriptor * desc, + ID3D12DescriptorHeap ** heap) +{ + g_return_val_if_fail (desc, FALSE); + g_return_val_if_fail (heap, FALSE); + + *heap = desc->heap.Get (); + (*heap)->AddRef (); + + return TRUE; +} diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12descriptorpool.h b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12descriptorpool.h new file mode 100644 index 0000000000..4d530167db --- /dev/null +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12descriptorpool.h @@ -0,0 +1,50 @@ +/* GStreamer + * Copyright (C) 2023 Seungha Yang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include +#include +#include "gstd3d12_fwd.h" + +G_BEGIN_DECLS + +#define GST_TYPE_D3D12_DESCRIPTOR_POOL (gst_d3d12_descriptor_pool_get_type()) +G_DECLARE_FINAL_TYPE (GstD3D12DescriptorPool, + gst_d3d12_descriptor_pool, GST, D3D12_DESCRIPTOR_POOL, GstObject); + +typedef struct _GstD3D12Descriptor GstD3D12Descriptor; + +GstD3D12DescriptorPool * gst_d3d12_descriptor_pool_new (GstD3D12Device * device, + const D3D12_DESCRIPTOR_HEAP_DESC * desc); + +gboolean gst_d3d12_descriptor_pool_acquire (GstD3D12DescriptorPool * pool, + GstD3D12Descriptor ** desc); + +GstD3D12Descriptor * gst_d3d12_descriptor_ref (GstD3D12Descriptor * desc); + +void gst_d3d12_descriptor_unref (GstD3D12Descriptor * desc); + +void gst_clear_d3d12_descriptor (GstD3D12Descriptor ** desc); + +gboolean gst_d3d12_descriptor_get_handle (GstD3D12Descriptor * desc, + ID3D12DescriptorHeap ** heap); + +G_END_DECLS + diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12device.cpp b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12device.cpp index 5e6a348d13..c9bf0f3454 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12device.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12device.cpp @@ -573,6 +573,13 @@ gst_d3d12_device_new_internal (const GstD3D12DeviceConstructData * data) return nullptr; } + ComPtr < ID3D12Device4 > device4; + hr = device.As (&device4); + if (FAILED (hr)) { + GST_WARNING ("ID3D12Device4 interface unavailable"); + return nullptr; + } + GstD3D12Device *self = (GstD3D12Device *) g_object_new (GST_TYPE_D3D12_DEVICE, nullptr); GstD3D12DevicePrivate *priv = self->priv; diff --git a/subprojects/gst-plugins-bad/sys/d3d12/meson.build b/subprojects/gst-plugins-bad/sys/d3d12/meson.build index c5d4d83d16..632f38eb00 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/meson.build +++ b/subprojects/gst-plugins-bad/sys/d3d12/meson.build @@ -2,7 +2,10 @@ d3d12_sources = [ 'gstd3d12av1dec.cpp', 'gstd3d12basefilter.cpp', 'gstd3d12bufferpool.cpp', + 'gstd3d12commandallocatorpool.cpp', + 'gstd3d12commandlistpool.cpp', 'gstd3d12decoder.cpp', + 'gstd3d12descriptorpool.cpp', 'gstd3d12device.cpp', 'gstd3d12download.cpp', 'gstd3d12fence.cpp',