mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-22 09:41:07 +00:00
d3d12: Add gst_d3d12_get_copyable_footprints() method
This helper method will calculate buffer resource size and layout required for (mutiple) texture resources to be stored in a single buffer resource Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7480>
This commit is contained in:
parent
f3589b57d2
commit
e962af3064
2 changed files with 112 additions and 0 deletions
|
@ -25,6 +25,7 @@
|
|||
#include "gstd3d12-private.h"
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <directx/d3dx12.h>
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
static std::recursive_mutex context_lock_;
|
||||
|
@ -672,6 +673,110 @@ gst_d3d12_buffer_set_fence (GstBuffer * buffer, ID3D12Fence * fence,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_align_desc (D3D12_RESOURCE_DESC & desc)
|
||||
{
|
||||
UINT width_align =
|
||||
D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetWidthAlignment (desc.Format);
|
||||
UINT height_align =
|
||||
D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetHeightAlignment (desc.Format);
|
||||
|
||||
if (width_align > 1)
|
||||
desc.Width = GST_ROUND_UP_N (desc.Width, (UINT64) width_align);
|
||||
|
||||
if (height_align > 1)
|
||||
desc.Height = GST_ROUND_UP_N (desc.Height, height_align);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_d3d12_get_copyable_footprints:
|
||||
* @device: a GstD3D12Device
|
||||
* @info: a GstVideoInfo
|
||||
* @layout: (out caller-allocates): copyable footprints
|
||||
* @size: (out): total size in bytes
|
||||
*
|
||||
* Calculates copyable footprints for given @info
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Since: 1.26
|
||||
*/
|
||||
gboolean
|
||||
gst_d3d12_get_copyable_footprints (GstD3D12Device * device,
|
||||
const GstVideoInfo * info,
|
||||
D3D12_PLACED_SUBRESOURCE_FOOTPRINT layout[GST_VIDEO_MAX_PLANES],
|
||||
guint64 * size)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_D3D12_DEVICE (device), 0);
|
||||
g_return_val_if_fail (info, 0);
|
||||
|
||||
GstD3D12Format format12;
|
||||
|
||||
if (!gst_d3d12_device_get_format (device, GST_VIDEO_INFO_FORMAT (info),
|
||||
&format12)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
auto device_handle = gst_d3d12_device_get_device_handle (device);
|
||||
auto dxgi_format = format12.dxgi_format;
|
||||
|
||||
if (dxgi_format != DXGI_FORMAT_UNKNOWN) {
|
||||
D3D12_RESOURCE_DESC desc = CD3DX12_RESOURCE_DESC::Tex2D (dxgi_format,
|
||||
info->width, info->height, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_NONE);
|
||||
|
||||
do_align_desc (desc);
|
||||
device_handle->GetCopyableFootprints (&desc, 0,
|
||||
D3D12GetFormatPlaneCount (device_handle, dxgi_format), 0, layout,
|
||||
nullptr, nullptr, size);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
auto finfo = info->finfo;
|
||||
UINT64 base_offset = 0;
|
||||
D3D12_PLACED_SUBRESOURCE_FOOTPRINT tmp_layout[GST_VIDEO_MAX_PLANES];
|
||||
|
||||
for (guint i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
|
||||
dxgi_format = format12.resource_format[i];
|
||||
|
||||
if (dxgi_format == DXGI_FORMAT_UNKNOWN)
|
||||
break;
|
||||
|
||||
gint comp[GST_VIDEO_MAX_COMPONENTS];
|
||||
gst_video_format_info_component (finfo, i, comp);
|
||||
|
||||
guint width = GST_VIDEO_INFO_COMP_WIDTH (info, comp[0]);
|
||||
guint height = GST_VIDEO_INFO_COMP_HEIGHT (info, comp[0]);
|
||||
width = MAX (width, 1);
|
||||
height = MAX (height, 1);
|
||||
|
||||
D3D12_RESOURCE_DESC desc = CD3DX12_RESOURCE_DESC::Tex2D (dxgi_format,
|
||||
width, height, 1, 1, 1, 0, D3D12_RESOURCE_FLAG_NONE);
|
||||
|
||||
do_align_desc (desc);
|
||||
|
||||
device_handle->GetCopyableFootprints (&desc,
|
||||
0, 1, base_offset, &tmp_layout[i], nullptr, nullptr, nullptr);
|
||||
base_offset = tmp_layout[i].Offset +
|
||||
(tmp_layout[i].Footprint.RowPitch * tmp_layout[i].Footprint.Height);
|
||||
base_offset = GST_ROUND_UP_N (base_offset,
|
||||
D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
|
||||
}
|
||||
|
||||
if (layout) {
|
||||
for (guint i = 0; i < GST_VIDEO_INFO_N_PLANES (info); i++) {
|
||||
layout[i] = tmp_layout[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (size) {
|
||||
D3D12_PLACED_SUBRESOURCE_FOOTPRINT *last =
|
||||
&tmp_layout[GST_VIDEO_INFO_N_PLANES (info) - 1];
|
||||
*size = last->Offset + (last->Footprint.RowPitch * last->Footprint.Height);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* _gst_d3d12_result:
|
||||
* @result: HRESULT D3D12 API return code
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/d3d12/gstd3d12_fwd.h>
|
||||
#include <gst/video/video.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
@ -71,6 +72,12 @@ void gst_d3d12_buffer_set_fence (GstBuffer * buffer,
|
|||
guint64 fence_value,
|
||||
gboolean wait);
|
||||
|
||||
GST_D3D12_API
|
||||
gboolean gst_d3d12_get_copyable_footprints (GstD3D12Device * device,
|
||||
const GstVideoInfo * info,
|
||||
D3D12_PLACED_SUBRESOURCE_FOOTPRINT layout[GST_VIDEO_MAX_PLANES],
|
||||
guint64 * size);
|
||||
|
||||
GST_D3D12_API
|
||||
gboolean _gst_d3d12_result (HRESULT hr,
|
||||
GstD3D12Device * device,
|
||||
|
|
Loading…
Reference in a new issue