From: Seungha Yang Date: Sun, 6 Feb 2022 12:36:28 +0000 (+0900) Subject: d3d11memory: Add support for ID3D11Buffer X-Git-Tag: 1.22.0~2506 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a37da515f44a10b074224a270911518b3ecdba68;p=platform%2Fupstream%2Fgstreamer.git d3d11memory: Add support for ID3D11Buffer Allow wrap ID3D11Buffer via GstD3D11Memory object At the moment, only staging ID3D11Buffer is supported. Part-of: --- diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11bufferpool.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11bufferpool.cpp index 14cc8b1..eb72f2f 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11bufferpool.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11bufferpool.cpp @@ -278,7 +278,7 @@ gst_d3d11_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) return FALSE; } - if (!gst_d3d11_memory_get_texture_stride (GST_D3D11_MEMORY_CAST (mem), + if (!gst_d3d11_memory_get_resource_stride (GST_D3D11_MEMORY_CAST (mem), &stride) || stride < desc[i].Width) { GST_ERROR_OBJECT (self, "Failed to calculate stride"); diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.cpp index 77d26fc..417015f 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.cpp @@ -247,9 +247,12 @@ gst_d3d11_allocation_params_init (GType type) struct _GstD3D11MemoryPrivate { ID3D11Texture2D *texture; - ID3D11Texture2D *staging; + ID3D11Buffer *buffer; + + ID3D11Resource *staging; D3D11_TEXTURE2D_DESC desc; + D3D11_BUFFER_DESC buffer_desc; guint subresource_index; @@ -265,6 +268,7 @@ struct _GstD3D11MemoryPrivate D3D11_MAPPED_SUBRESOURCE map; + GstD3D11MemoryNativeType native_type; GMutex lock; gint cpu_map_count; @@ -320,11 +324,10 @@ gst_d3d11_memory_map_cpu_access (GstD3D11Memory * dmem, D3D11_MAP map_type) { GstD3D11MemoryPrivate *priv = dmem->priv; HRESULT hr; - ID3D11Resource *staging = (ID3D11Resource *) priv->staging; ID3D11DeviceContext *device_context = gst_d3d11_device_get_device_context_handle (dmem->device); - hr = device_context->Map (staging, 0, map_type, 0, &priv->map); + hr = device_context->Map (priv->staging, 0, map_type, 0, &priv->map); if (!gst_d3d11_result (hr, dmem->device)) { GST_ERROR_OBJECT (GST_MEMORY_CAST (dmem)->allocator, @@ -379,36 +382,46 @@ gst_d3d11_memory_map_full (GstMemory * mem, GstMapInfo * info, gsize maxsize) GST_D3D11_MEMORY_LOCK (dmem); if ((flags & GST_MAP_D3D11) == GST_MAP_D3D11) { - gst_d3d11_memory_upload (dmem); - GST_MEMORY_FLAG_UNSET (dmem, GST_D3D11_MEMORY_TRANSFER_NEED_UPLOAD); + if (priv->native_type == GST_D3D11_MEMORY_NATIVE_TYPE_BUFFER) { + /* FIXME: handle non-staging buffer */ + g_assert (priv->buffer != nullptr); + ret = priv->buffer; + } else { + gst_d3d11_memory_upload (dmem); + GST_MEMORY_FLAG_UNSET (dmem, GST_D3D11_MEMORY_TRANSFER_NEED_UPLOAD); - if ((flags & GST_MAP_WRITE) == GST_MAP_WRITE) - GST_MINI_OBJECT_FLAG_SET (dmem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD); + if ((flags & GST_MAP_WRITE) == GST_MAP_WRITE) + GST_MINI_OBJECT_FLAG_SET (dmem, + GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD); - g_assert (priv->texture != NULL); - ret = priv->texture; - goto out; + g_assert (priv->texture != NULL); + ret = priv->texture; + goto out; + } } if (priv->cpu_map_count == 0) { D3D11_MAP map_type; - /* Allocate staging texture for CPU access */ - if (!priv->staging) { - priv->staging = gst_d3d11_allocate_staging_texture (dmem->device, - &priv->desc); + /* FIXME: handle non-staging buffer */ + if (priv->native_type == GST_D3D11_MEMORY_NATIVE_TYPE_TEXTURE_2D) { + /* Allocate staging texture for CPU access */ if (!priv->staging) { - GST_ERROR_OBJECT (mem->allocator, "Couldn't create staging texture"); - goto out; + priv->staging = gst_d3d11_allocate_staging_texture (dmem->device, + &priv->desc); + if (!priv->staging) { + GST_ERROR_OBJECT (mem->allocator, "Couldn't create staging texture"); + goto out; + } + + /* first memory, always need download to staging */ + GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD); } - /* first memory, always need download to staging */ - GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD); + gst_d3d11_memory_download (dmem); } - gst_d3d11_memory_download (dmem); map_type = gst_d3d11_map_flags_to_d3d11 (flags); - if (!gst_d3d11_memory_map_cpu_access (dmem, map_type)) { GST_ERROR_OBJECT (mem->allocator, "Couldn't map staging texture"); goto out; @@ -436,11 +449,10 @@ static void gst_d3d11_memory_unmap_cpu_access (GstD3D11Memory * dmem) { GstD3D11MemoryPrivate *priv = dmem->priv; - ID3D11Resource *staging = (ID3D11Resource *) priv->staging; ID3D11DeviceContext *device_context = gst_d3d11_device_get_device_context_handle (dmem->device); - device_context->Unmap (staging, 0); + device_context->Unmap (priv->staging, 0); } static void @@ -541,6 +553,23 @@ gst_is_d3d11_memory (GstMemory * mem) } /** + * gst_d3d11_memory_get_native_type: + * @mem: a #GstD3D11Memory + * + * Returns: a #GstD3D11MemoryNativeType + * + * Since: 1.22 + */ +GstD3D11MemoryNativeType +gst_d3d11_memory_get_native_type (GstD3D11Memory * mem) +{ + if (!gst_is_d3d11_memory (GST_MEMORY_CAST (mem))) + return GST_D3D11_MEMORY_NATIVE_TYPE_INVALID; + + return mem->priv->native_type; +} + +/** * gst_d3d11_memory_init_once: * * Initializes the Direct3D11 Texture allocator. It is safe to call @@ -569,20 +598,29 @@ gst_d3d11_memory_init_once (void) } /** - * gst_d3d11_memory_get_texture_handle: + * gst_d3d11_memory_get_resource_handle: * @mem: a #GstD3D11Memory * - * Returns: (transfer none): a ID3D11Texture2D handle. Caller must not release + * Returns: (transfer none): a ID3D11Resource handle. Caller must not release * returned handle. * - * Since: 1.20 + * Since: 1.22 */ -ID3D11Texture2D * -gst_d3d11_memory_get_texture_handle (GstD3D11Memory * mem) +ID3D11Resource * +gst_d3d11_memory_get_resource_handle (GstD3D11Memory * mem) { g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), NULL); - return mem->priv->texture; + switch (mem->priv->native_type) { + case GST_D3D11_MEMORY_NATIVE_TYPE_BUFFER: + return mem->priv->buffer; + case GST_D3D11_MEMORY_NATIVE_TYPE_TEXTURE_2D: + return mem->priv->texture; + default: + break; + } + + return nullptr; } /** @@ -598,6 +636,9 @@ gst_d3d11_memory_get_subresource_index (GstD3D11Memory * mem) { g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), 0); + if (mem->priv->native_type != GST_D3D11_MEMORY_NATIVE_TYPE_TEXTURE_2D) + return 0; + return mem->priv->subresource_index; } @@ -619,13 +660,51 @@ gst_d3d11_memory_get_texture_desc (GstD3D11Memory * mem, g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), FALSE); g_return_val_if_fail (desc != NULL, FALSE); + if (mem->priv->native_type != GST_D3D11_MEMORY_NATIVE_TYPE_TEXTURE_2D) + return FALSE; + *desc = mem->priv->desc; return TRUE; } +/** + * gst_d3d11_memory_get_buffer_desc: + * @mem: a #GstD3D11Memory + * @desc: (out): a D3D11_BUFFER_DESC + * + * Fill @desc with D3D11_BUFFER_DESC for ID3D11Buffer + * + * Returns: %TRUE if successeed + * + * Since: 1.22 + */ +gboolean +gst_d3d11_memory_get_buffer_desc (GstD3D11Memory * mem, + D3D11_BUFFER_DESC * desc) +{ + g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), FALSE); + g_return_val_if_fail (desc != NULL, FALSE); + + if (mem->priv->native_type != GST_D3D11_MEMORY_NATIVE_TYPE_BUFFER) + return FALSE; + + *desc = mem->priv->buffer_desc; + + return TRUE; +} + +/** + * gst_d3d11_memory_get_resource_stride: + * @mem: a #GstD3D11Memory + * @stride: (out): stride of resource + * + * Returns: %TRUE if successeed + * + * Since: 1.22 + */ gboolean -gst_d3d11_memory_get_texture_stride (GstD3D11Memory * mem, guint * stride) +gst_d3d11_memory_get_resource_stride (GstD3D11Memory * mem, guint * stride) { g_return_val_if_fail (gst_is_d3d11_memory (GST_MEMORY_CAST (mem)), FALSE); g_return_val_if_fail (stride != NULL, FALSE); @@ -732,6 +811,9 @@ gst_d3d11_memory_ensure_shader_resource_view (GstD3D11Memory * mem) GstD3D11MemoryPrivate *priv = mem->priv; gboolean ret = FALSE; + if (mem->priv->native_type != GST_D3D11_MEMORY_NATIVE_TYPE_TEXTURE_2D) + return FALSE; + if (!(priv->desc.BindFlags & D3D11_BIND_SHADER_RESOURCE)) { GST_LOG_OBJECT (GST_MEMORY_CAST (mem)->allocator, "Need BindFlags, current flag 0x%x", priv->desc.BindFlags); @@ -888,6 +970,9 @@ gst_d3d11_memory_ensure_render_target_view (GstD3D11Memory * mem) GstD3D11MemoryPrivate *priv = mem->priv; gboolean ret = FALSE; + if (mem->priv->native_type != GST_D3D11_MEMORY_NATIVE_TYPE_TEXTURE_2D) + return FALSE; + if (!(priv->desc.BindFlags & D3D11_BIND_RENDER_TARGET)) { GST_WARNING_OBJECT (GST_MEMORY_CAST (mem)->allocator, "Need BindFlags, current flag 0x%x", priv->desc.BindFlags); @@ -969,6 +1054,9 @@ gst_d3d11_memory_ensure_decoder_output_view (GstD3D11Memory * mem, HRESULT hr; gboolean ret = FALSE; + if (mem->priv->native_type != GST_D3D11_MEMORY_NATIVE_TYPE_TEXTURE_2D) + return FALSE; + allocator = GST_D3D11_ALLOCATOR (GST_MEMORY_CAST (mem)->allocator); if (!(dmem_priv->desc.BindFlags & D3D11_BIND_DECODER)) { @@ -1066,6 +1154,9 @@ gst_d3d11_memory_ensure_processor_input_view (GstD3D11Memory * mem, HRESULT hr; gboolean ret = FALSE; + if (mem->priv->native_type != GST_D3D11_MEMORY_NATIVE_TYPE_TEXTURE_2D) + return FALSE; + allocator = GST_D3D11_ALLOCATOR (GST_MEMORY_CAST (mem)->allocator); if (!check_bind_flags_for_processor_input_view (dmem_priv->desc.BindFlags)) { @@ -1139,6 +1230,9 @@ gst_d3d11_memory_ensure_processor_output_view (GstD3D11Memory * mem, HRESULT hr; gboolean ret; + if (mem->priv->native_type != GST_D3D11_MEMORY_NATIVE_TYPE_TEXTURE_2D) + return FALSE; + memset (&desc, 0, sizeof (D3D11_VIDEO_PROCESSOR_OUTPUT_VIEW_DESC)); allocator = GST_D3D11_ALLOCATOR (GST_MEMORY_CAST (mem)->allocator); @@ -1253,6 +1347,9 @@ gst_d3d11_memory_copy (GstMemory * mem, gssize offset, gssize size) UINT bind_flags = 0; UINT supported_flags = 0; + if (dmem->priv->native_type != GST_D3D11_MEMORY_NATIVE_TYPE_TEXTURE_2D) + return priv->fallback_copy (mem, offset, size); + /* non-zero offset or different size is not supported */ if (offset != 0 || (size != -1 && (gsize) size != mem->size)) { GST_DEBUG_OBJECT (alloc, "Different size/offset, try fallback copy"); @@ -1364,6 +1461,7 @@ gst_d3d11_allocator_free (GstAllocator * allocator, GstMemory * mem) GST_D3D11_CLEAR_COM (dmem_priv->processor_output_view); GST_D3D11_CLEAR_COM (dmem_priv->texture); GST_D3D11_CLEAR_COM (dmem_priv->staging); + GST_D3D11_CLEAR_COM (dmem_priv->buffer); gst_clear_object (&dmem->device); g_mutex_clear (&dmem_priv->lock); @@ -1386,6 +1484,7 @@ gst_d3d11_allocator_alloc_wrapped (GstD3D11Allocator * self, g_mutex_init (&mem->priv->lock); mem->priv->texture = texture; mem->priv->desc = *desc; + mem->priv->native_type = GST_D3D11_MEMORY_NATIVE_TYPE_TEXTURE_2D; mem->device = (GstD3D11Device *) gst_object_ref (device); /* This is staging texture as well */ @@ -1449,6 +1548,59 @@ gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator, return mem; } +/** + * gst_d3d11_allocator_alloc_buffer: + * @allocator: a #GstD3D11Allocator + * @device: a #GstD3D11Device + * @desc: a D3D11_BUFFER_DESC struct + * + * Returns: a newly allocated #GstD3D11Memory with given parameters. + * + * Since: 1.22 + */ +GstMemory * +gst_d3d11_allocator_alloc_buffer (GstD3D11Allocator * allocator, + GstD3D11Device * device, const D3D11_BUFFER_DESC * desc) +{ + GstD3D11Memory *mem; + ID3D11Buffer *buffer; + ID3D11Device *device_handle; + HRESULT hr; + + g_return_val_if_fail (GST_IS_D3D11_ALLOCATOR (allocator), nullptr); + g_return_val_if_fail (GST_IS_D3D11_DEVICE (device), nullptr); + g_return_val_if_fail (desc != nullptr, nullptr); + + if (desc->Usage != D3D11_USAGE_STAGING) { + GST_FIXME_OBJECT (allocator, "Non staging buffer is not supported"); + return nullptr; + } + + device_handle = gst_d3d11_device_get_device_handle (device); + + hr = device_handle->CreateBuffer (desc, nullptr, &buffer); + if (!gst_d3d11_result (hr, device)) { + GST_ERROR_OBJECT (allocator, "Couldn't create buffer"); + return nullptr; + } + + mem = g_new0 (GstD3D11Memory, 1); + mem->priv = g_new0 (GstD3D11MemoryPrivate, 1); + + gst_memory_init (GST_MEMORY_CAST (mem), + (GstMemoryFlags) 0, GST_ALLOCATOR_CAST (allocator), nullptr, 0, 0, 0, 0); + g_mutex_init (&mem->priv->lock); + mem->priv->buffer = buffer; + mem->priv->buffer_desc = *desc; + mem->priv->native_type = GST_D3D11_MEMORY_NATIVE_TYPE_BUFFER; + mem->device = (GstD3D11Device *) gst_object_ref (device); + + GST_MEMORY_CAST (mem)->maxsize = GST_MEMORY_CAST (mem)->size = + desc->ByteWidth; + + return GST_MEMORY_CAST (mem); +} + gboolean gst_d3d11_allocator_set_active (GstD3D11Allocator * allocator, gboolean active) { diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.h b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.h index a80bf7b..841188c 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11memory.h @@ -106,6 +106,21 @@ typedef enum GST_D3D11_MEMORY_TRANSFER_NEED_UPLOAD = (GST_MEMORY_FLAG_LAST << 1) } GstD3D11MemoryTransfer; +/** + * GstD3D11MemoryNativeType: + * @GST_D3D11_MEMORY_NATIVE_TYPE_INVALID: not a valid object type + * @GST_D3D11_MEMORY_OBJECT_TYPE_BUFFER: memory holds ID3D11Buffer object + * @GST_D3D11_MEMORY_OBJECT_TYPE_TEXTURE_2D: memory holds ID3D11Texture2D object + * + * Since: 1.22 + */ +typedef enum +{ + GST_D3D11_MEMORY_NATIVE_TYPE_INVALID = 0, + GST_D3D11_MEMORY_NATIVE_TYPE_BUFFER, + GST_D3D11_MEMORY_NATIVE_TYPE_TEXTURE_2D, +} GstD3D11MemoryNativeType; + struct _GstD3D11AllocationParams { /* Texture description per plane */ @@ -162,15 +177,22 @@ GST_D3D11_API gboolean gst_is_d3d11_memory (GstMemory * mem); GST_D3D11_API -ID3D11Texture2D * gst_d3d11_memory_get_texture_handle (GstD3D11Memory * mem); +GstD3D11MemoryNativeType gst_d3d11_memory_get_native_type (GstD3D11Memory * mem); + +GST_D3D11_API +ID3D11Resource * gst_d3d11_memory_get_resource_handle (GstD3D11Memory * mem); GST_D3D11_API gboolean gst_d3d11_memory_get_texture_desc (GstD3D11Memory * mem, D3D11_TEXTURE2D_DESC * desc); GST_D3D11_API -gboolean gst_d3d11_memory_get_texture_stride (GstD3D11Memory * mem, - guint * stride); +gboolean gst_d3d11_memory_get_buffer_desc (GstD3D11Memory * mem, + D3D11_BUFFER_DESC * desc); + +GST_D3D11_API +gboolean gst_d3d11_memory_get_resource_stride (GstD3D11Memory * mem, + guint * stride); GST_D3D11_API guint gst_d3d11_memory_get_subresource_index (GstD3D11Memory * mem); @@ -234,6 +256,11 @@ GstMemory * gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator, const D3D11_TEXTURE2D_DESC * desc); GST_D3D11_API +GstMemory * gst_d3d11_allocator_alloc_buffer (GstD3D11Allocator * allocator, + GstD3D11Device * device, + const D3D11_BUFFER_DESC * desc); + +GST_D3D11_API gboolean gst_d3d11_allocator_set_active (GstD3D11Allocator * allocator, gboolean active); diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11stagingbufferpool.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11stagingbufferpool.cpp index 40912f9..fc87521 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11stagingbufferpool.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d11/gstd3d11stagingbufferpool.cpp @@ -225,7 +225,7 @@ gst_d3d11_staging_buffer_pool_set_config (GstBufferPool * pool, return FALSE; } - if (!gst_d3d11_memory_get_texture_stride (GST_D3D11_MEMORY_CAST (mem), + if (!gst_d3d11_memory_get_resource_stride (GST_D3D11_MEMORY_CAST (mem), &stride) || stride < priv->desc[i].Width) { GST_ERROR_OBJECT (self, "Failed to calculate stride"); diff --git a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11pluginutils.cpp b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11pluginutils.cpp index 6c17748..7a253d4 100644 --- a/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11pluginutils.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d11/gstd3d11pluginutils.cpp @@ -649,7 +649,7 @@ gst_d3d11_allocate_staging_buffer_for (GstBuffer * buffer, goto error; } - if (!gst_d3d11_memory_get_texture_stride (new_mem, &cur_stride) || + if (!gst_d3d11_memory_get_resource_stride (new_mem, &cur_stride) || cur_stride < staging_desc.Width) { GST_ERROR ("Failed to calculate memory size"); gst_memory_unref (GST_MEMORY_CAST (mem));