From 7bfdeaf161d08824d1f2c1766d50f0193fa8ca40 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Fri, 20 Dec 2019 22:50:55 +0900 Subject: [PATCH] d3d11: Add support for Array typed texture memory A ID3D11Texture2D memory can consist of multiple planes with array. For array typed memory, GstD3D11Allocator will allocate new GstD3D11Memory with increased reference count to the ID3D11Texture2D but different array index. --- sys/d3d11/gstd3d11bufferpool.c | 26 +++++++++++++++++++-- sys/d3d11/gstd3d11memory.c | 51 +++++++++++++++++++++++++++++++++++++----- sys/d3d11/gstd3d11memory.h | 16 +++++++++++++ 3 files changed, 85 insertions(+), 8 deletions(-) diff --git a/sys/d3d11/gstd3d11bufferpool.c b/sys/d3d11/gstd3d11bufferpool.c index 123ef8f..63bd683 100644 --- a/sys/d3d11/gstd3d11bufferpool.c +++ b/sys/d3d11/gstd3d11bufferpool.c @@ -109,6 +109,8 @@ gst_d3d11_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) guint min_buffers, max_buffers; GstAllocator *allocator = NULL; gboolean ret = TRUE; + D3D11_TEXTURE2D_DESC *desc; + gint i; if (!gst_buffer_pool_config_get_params (config, &caps, NULL, &min_buffers, &max_buffers)) @@ -155,11 +157,11 @@ gst_d3d11_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) } #ifndef GST_DISABLE_GST_DEBUG { - D3D11_TEXTURE2D_DESC *desc; - gint i; desc = priv->d3d11_params->desc; GST_LOG_OBJECT (self, "Direct3D11 Allocation params"); + GST_LOG_OBJECT (self, "\tD3D11AllocationFlags: 0x%x", + priv->d3d11_params->flags); for (i = 0; GST_VIDEO_MAX_PLANES; i++) { if (desc[i].Format == DXGI_FORMAT_UNKNOWN) break; @@ -181,6 +183,26 @@ gst_d3d11_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) } #endif + if ((priv->d3d11_params->flags & GST_D3D11_ALLOCATION_FLAG_TEXTURE_ARRAY)) { + guint max_array_size = 0; + desc = priv->d3d11_params->desc; + + for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) { + if (desc[i].Format == DXGI_FORMAT_UNKNOWN) + break; + + if (desc[i].ArraySize > max_array_size) + max_array_size = desc[i].ArraySize; + } + + if (max_buffers == 0 || max_buffers > max_array_size) { + GST_WARNING_OBJECT (pool, + "Array pool is requested but allowed pool size %d > ArraySize %d", + max_buffers, max_array_size); + max_buffers = max_array_size; + } + } + gst_d3d11_buffer_pool_alloc (pool, &priv->initial_buffer, NULL); if (!priv->initial_buffer) { diff --git a/sys/d3d11/gstd3d11memory.c b/sys/d3d11/gstd3d11memory.c index 13e4818..b2eacf4 100644 --- a/sys/d3d11/gstd3d11memory.c +++ b/sys/d3d11/gstd3d11memory.c @@ -212,7 +212,7 @@ map_cpu_access_data (GstD3D11Memory * dmem, D3D11_MAP map_type) gst_d3d11_device_lock (dmem->device); if (GST_MEMORY_FLAG_IS_SET (dmem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD)) { ID3D11DeviceContext_CopySubresourceRegion (device_context, - staging, 0, 0, 0, 0, texture, 0, NULL); + staging, 0, 0, 0, 0, texture, dmem->subresource_index, NULL); } hr = ID3D11DeviceContext_Map (device_context, @@ -249,7 +249,7 @@ gst_d3d11_memory_map (GstMemory * mem, gsize maxsize, GstMapFlags flags) gst_d3d11_device_lock (dmem->device); ID3D11DeviceContext_CopySubresourceRegion (device_context, - (ID3D11Resource *) dmem->texture, 0, 0, 0, 0, + (ID3D11Resource *) dmem->texture, dmem->subresource_index, 0, 0, 0, (ID3D11Resource *) dmem->staging, 0, NULL); gst_d3d11_device_unlock (dmem->device); } @@ -396,6 +396,11 @@ gst_d3d11_allocator_dispose (GObject * object) { GstD3D11Allocator *alloc = GST_D3D11_ALLOCATOR (object); + if (alloc->device && alloc->texture) { + gst_d3d11_device_release_texture (alloc->device, alloc->texture); + alloc->texture = NULL; + } + gst_clear_object (&alloc->device); G_OBJECT_CLASS (parent_class)->dispose (object); @@ -636,6 +641,8 @@ gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator, gsize *size; gboolean is_first = FALSE; GstMemoryFlags memory_flags; + guint index_to_use = 0; + GstD3D11MemoryType type = GST_D3D11_MEMORY_TYPE_TEXTURE; g_return_val_if_fail (GST_IS_D3D11_ALLOCATOR (allocator), NULL); g_return_val_if_fail (params != NULL, NULL); @@ -657,10 +664,38 @@ gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator, if (*size == 0) is_first = TRUE; - texture = gst_d3d11_device_create_texture (device, desc, NULL); - if (!texture) { - GST_ERROR_OBJECT (allocator, "Couldn't create texture"); - goto error; + if ((params->flags & GST_D3D11_ALLOCATION_FLAG_TEXTURE_ARRAY)) { + gint i; + for (i = 0; i < desc->ArraySize; i++) { + if (allocator->array_in_use[i] == 0) { + index_to_use = i; + break; + } + } + + if (i == desc->ArraySize) { + GST_ERROR_OBJECT (allocator, "All elements in array are used now"); + goto error; + } + + if (!allocator->texture) { + allocator->texture = gst_d3d11_device_create_texture (device, desc, NULL); + if (!allocator->texture) { + GST_ERROR_OBJECT (allocator, "Couldn't create texture"); + goto error; + } + } + + ID3D11Texture2D_AddRef (allocator->texture); + texture = allocator->texture; + + type = GST_D3D11_MEMORY_TYPE_ARRAY; + } else { + texture = gst_d3d11_device_create_texture (device, desc, NULL); + if (!texture) { + GST_ERROR_OBJECT (allocator, "Couldn't create texture"); + goto error; + } } /* per plane, allocated staging texture to calculate actual size, @@ -713,6 +748,10 @@ gst_d3d11_allocator_alloc (GstD3D11Allocator * allocator, mem->texture = texture; mem->staging = staging; mem->device = gst_object_ref (device); + mem->type = type; + mem->subresource_index = index_to_use; + if (type == GST_D3D11_MEMORY_TYPE_ARRAY) + allocator->array_in_use[index_to_use] = 1; if (staging) GST_MINI_OBJECT_FLAG_SET (mem, GST_D3D11_MEMORY_TRANSFER_NEED_DOWNLOAD); diff --git a/sys/d3d11/gstd3d11memory.h b/sys/d3d11/gstd3d11memory.h index dc0515d..74a3d36 100644 --- a/sys/d3d11/gstd3d11memory.h +++ b/sys/d3d11/gstd3d11memory.h @@ -57,10 +57,12 @@ G_BEGIN_DECLS * GstD3D11AllocationFlags: * GST_D3D11_ALLOCATION_FLAG_USE_RESOURCE_FORMAT: Allocate texture with resource format * per planes instead of the direct use of DXGI format + * GST_D3D11_ALLOCATION_FLAG_TEXTURE_ARRAY: Indicates each allocated texture should be array type */ typedef enum { GST_D3D11_ALLOCATION_FLAG_USE_RESOURCE_FORMAT = (1 << 0), + GST_D3D11_ALLOCATION_FLAG_TEXTURE_ARRAY = (1 << 1), } GstD3D11AllocationFlags; /** @@ -97,6 +99,12 @@ struct _GstD3D11AllocationParams gpointer _gst_reserved[GST_PADDING_LARGE]; }; +typedef enum +{ + GST_D3D11_MEMORY_TYPE_TEXTURE = 0, + GST_D3D11_MEMORY_TYPE_ARRAY = 1, +} GstD3D11MemoryType; + struct _GstD3D11Memory { GstMemory mem; @@ -116,6 +124,10 @@ struct _GstD3D11Memory GstVideoInfo info; guint plane; + GstD3D11MemoryType type; + + /* > 0 if this is Array typed memory */ + guint subresource_index; D3D11_TEXTURE2D_DESC desc; D3D11_MAPPED_SUBRESOURCE map; @@ -131,6 +143,10 @@ struct _GstD3D11Allocator GstD3D11Device *device; + /* parent textrure when array typed memory is used */ + ID3D11Texture2D *texture; + guint8 array_in_use [D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION]; + /*< private >*/ gpointer _gst_reserved[GST_PADDING]; }; -- 2.7.4