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.
This commit is contained in:
Seungha Yang 2019-12-20 22:50:55 +09:00 committed by GStreamer Merge Bot
parent add7878e14
commit 7bfdeaf161
3 changed files with 85 additions and 8 deletions

View file

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

View file

@ -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);

View file

@ -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];
};