mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-18 07:47:17 +00:00
d3d11memory: Update alloc_wrapped() API to avoid staging texture alloc
Add size parameter and use it for CPU accessible memory size instead of allocating staging texture per API call. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2713>
This commit is contained in:
parent
76dbe45b83
commit
347ad181be
6 changed files with 43 additions and 62 deletions
|
@ -41,16 +41,6 @@ void gst_d3d11_device_dxgi_debug (GstD3D11Device * device,
|
|||
const gchar * function,
|
||||
gint line);
|
||||
|
||||
/* Memory allocated by this method does not hold correct size.
|
||||
* So this is private method and only plugins in -bad are expected to call
|
||||
* this method */
|
||||
GST_D3D11_API
|
||||
GstMemory * gst_d3d11_allocator_alloc_wrapped_native_size (GstD3D11Allocator * allocator,
|
||||
GstD3D11Device * device,
|
||||
ID3D11Texture2D * texture,
|
||||
gpointer user_data,
|
||||
GDestroyNotify notify);
|
||||
|
||||
#define GST_D3D11_CLEAR_COM(obj) G_STMT_START { \
|
||||
if (obj) { \
|
||||
(obj)->Release (); \
|
||||
|
|
|
@ -1639,12 +1639,21 @@ gst_d3d11_allocator_alloc_buffer (GstD3D11Allocator * allocator,
|
|||
* @allocator: a #GstD3D11Allocator
|
||||
* @device: a #GstD3D11Device
|
||||
* @texture: a ID3D11Texture2D
|
||||
* @size: CPU accessible memory size
|
||||
* @user_data: (allow-none): user data
|
||||
* @notify: (allow-none): called with @user_data when the memory is freed
|
||||
*
|
||||
* Allocates memory object with @texture. The refcount of @texture
|
||||
* will be increased by one.
|
||||
*
|
||||
* Caller should set valid CPU acessible memory value to @size
|
||||
* (which is typically calculated by using staging texture and Map/Unmap)
|
||||
* or zero is allowed. In that case, allocator will create a temporary staging
|
||||
* texture to get the size and the temporary staging texture will be released.
|
||||
*
|
||||
* Caller must not be confused that @size is CPU accessible size, not raw
|
||||
* texture size.
|
||||
*
|
||||
* Returns: a newly allocated #GstD3D11Memory with given @texture
|
||||
* if successful, or %NULL if @texture is not a valid handle or configuration
|
||||
* is not supported.
|
||||
|
@ -1653,8 +1662,8 @@ gst_d3d11_allocator_alloc_buffer (GstD3D11Allocator * allocator,
|
|||
*/
|
||||
GstMemory *
|
||||
gst_d3d11_allocator_alloc_wrapped (GstD3D11Allocator * allocator,
|
||||
GstD3D11Device * device, ID3D11Texture2D * texture, gpointer user_data,
|
||||
GDestroyNotify notify)
|
||||
GstD3D11Device * device, ID3D11Texture2D * texture, gsize size,
|
||||
gpointer user_data, GDestroyNotify notify)
|
||||
{
|
||||
GstMemory *mem;
|
||||
GstD3D11Memory *dmem;
|
||||
|
@ -1678,10 +1687,14 @@ gst_d3d11_allocator_alloc_wrapped (GstD3D11Allocator * allocator,
|
|||
if (!mem)
|
||||
return nullptr;
|
||||
|
||||
if (!gst_d3d11_memory_update_size (mem)) {
|
||||
GST_ERROR_OBJECT (allocator, "Failed to calculate size");
|
||||
gst_memory_unref (mem);
|
||||
return nullptr;
|
||||
if (size == 0) {
|
||||
if (!gst_d3d11_memory_update_size (mem)) {
|
||||
GST_ERROR_OBJECT (allocator, "Failed to calculate size");
|
||||
gst_memory_unref (mem);
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
mem->maxsize = mem->size = size;
|
||||
}
|
||||
|
||||
dmem = GST_D3D11_MEMORY_CAST (mem);
|
||||
|
@ -1692,46 +1705,6 @@ gst_d3d11_allocator_alloc_wrapped (GstD3D11Allocator * allocator,
|
|||
return mem;
|
||||
}
|
||||
|
||||
GstMemory *
|
||||
gst_d3d11_allocator_alloc_wrapped_native_size (GstD3D11Allocator * allocator,
|
||||
GstD3D11Device * device, ID3D11Texture2D * texture, gpointer user_data,
|
||||
GDestroyNotify notify)
|
||||
{
|
||||
GstMemory *mem;
|
||||
GstD3D11Memory *dmem;
|
||||
D3D11_TEXTURE2D_DESC desc = { 0, };
|
||||
ID3D11Texture2D *tex = nullptr;
|
||||
HRESULT hr;
|
||||
gsize size;
|
||||
|
||||
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 (texture != nullptr, nullptr);
|
||||
|
||||
hr = texture->QueryInterface (IID_PPV_ARGS (&tex));
|
||||
if (FAILED (hr)) {
|
||||
GST_WARNING_OBJECT (allocator, "Not a valid texture handle");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
tex->GetDesc (&desc);
|
||||
mem = gst_d3d11_allocator_alloc_internal (allocator, device, &desc, tex);
|
||||
|
||||
if (!mem)
|
||||
return nullptr;
|
||||
|
||||
/* XXX: This is not correct memory size */
|
||||
size = desc.Width * desc.Height;
|
||||
mem->maxsize = mem->size = size;
|
||||
|
||||
dmem = GST_D3D11_MEMORY_CAST (mem);
|
||||
|
||||
dmem->priv->user_data = user_data;
|
||||
dmem->priv->notify = notify;
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_d3d11_allocator_set_active:
|
||||
* @allocator: a #GstD3D11Allocator
|
||||
|
|
|
@ -263,6 +263,7 @@ GST_D3D11_API
|
|||
GstMemory * gst_d3d11_allocator_alloc_wrapped (GstD3D11Allocator * allocator,
|
||||
GstD3D11Device * device,
|
||||
ID3D11Texture2D * texture,
|
||||
gsize size,
|
||||
gpointer user_data,
|
||||
GDestroyNotify notify);
|
||||
|
||||
|
|
|
@ -281,6 +281,7 @@ gst_d3d11_window_on_resize_default (GstD3D11Window * self, guint width,
|
|||
GstMemory *mem;
|
||||
GstD3D11Memory *dmem;
|
||||
ID3D11RenderTargetView *rtv;
|
||||
gsize size;
|
||||
|
||||
gst_d3d11_device_lock (device);
|
||||
|
||||
|
@ -304,8 +305,19 @@ gst_d3d11_window_on_resize_default (GstD3D11Window * self, guint width,
|
|||
goto done;
|
||||
}
|
||||
|
||||
mem = gst_d3d11_allocator_alloc_wrapped_native_size (self->allocator,
|
||||
self->device, backbuffer.Get (), nullptr, nullptr);
|
||||
backbuffer->GetDesc (&desc);
|
||||
size = desc.Width * desc.Height;
|
||||
/* flip mode swapchain supports only 4 formats, rgba/bgra/rgb10a2/rgba64.
|
||||
* The size passed in alloc_wrapped() is not important here, since we never
|
||||
* try mapping this for CPU access */
|
||||
if (desc.Format == DXGI_FORMAT_R16G16B16A16_FLOAT) {
|
||||
size *= 8;
|
||||
} else {
|
||||
size *= 4;
|
||||
}
|
||||
|
||||
mem = gst_d3d11_allocator_alloc_wrapped (self->allocator,
|
||||
self->device, backbuffer.Get (), size, nullptr, nullptr);
|
||||
if (!mem) {
|
||||
GST_ERROR_OBJECT (self, "Couldn't allocate wrapped memory");
|
||||
goto done;
|
||||
|
@ -322,7 +334,6 @@ gst_d3d11_window_on_resize_default (GstD3D11Window * self, guint width,
|
|||
self->backbuffer = gst_buffer_new ();
|
||||
gst_buffer_append_memory (self->backbuffer, mem);
|
||||
|
||||
backbuffer->GetDesc (&desc);
|
||||
self->surface_width = desc.Width;
|
||||
self->surface_height = desc.Height;
|
||||
|
||||
|
|
|
@ -238,8 +238,8 @@ gst_d3d11_window_dummy_open_shared_handle (GstD3D11Window * window,
|
|||
}
|
||||
}
|
||||
|
||||
mem = gst_d3d11_allocator_alloc_wrapped_native_size (window->allocator,
|
||||
device, texture.Get (), nullptr, nullptr);
|
||||
mem = gst_d3d11_allocator_alloc_wrapped (window->allocator,
|
||||
device, texture.Get (), desc.Width * desc.Height * 4, nullptr, nullptr);
|
||||
if (!mem) {
|
||||
GST_ERROR_OBJECT (window, "Couldn't allocate memory");
|
||||
return FALSE;
|
||||
|
|
|
@ -42,6 +42,7 @@ typedef struct
|
|||
|
||||
ID3D11Device *device;
|
||||
ID3D11DeviceContext *context;
|
||||
gsize mem_size;
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
GstVideoInfo video_info;
|
||||
|
@ -282,7 +283,8 @@ on_need_data (GstAppSrc * appsrc, guint length, gpointer user_data)
|
|||
* ID3D11Texture2D object, but in this example, we pass ownership via
|
||||
* user data */
|
||||
mem = gst_d3d11_allocator_alloc_wrapped (allocator, app_data->d3d11_device,
|
||||
texture, memory_data, (GDestroyNotify) on_memory_freed);
|
||||
texture, app_data->mem_size, memory_data,
|
||||
(GDestroyNotify) on_memory_freed);
|
||||
gst_object_unref (allocator);
|
||||
|
||||
if (!mem) {
|
||||
|
@ -290,6 +292,10 @@ on_need_data (GstAppSrc * appsrc, guint length, gpointer user_data)
|
|||
exit (1);
|
||||
}
|
||||
|
||||
/* update memory size with calculated value by allocator, and reuse it
|
||||
* for later alloc_wrapped() call to avoid allocating staging texture */
|
||||
app_data->mem_size = mem->size;
|
||||
|
||||
/* Calculates CPU accessible (via staging texture) memory layout.
|
||||
* GstD3D11Memory allows CPU access but application must calculate the layout
|
||||
* pitch would be likely different from width */
|
||||
|
|
Loading…
Reference in a new issue