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:
Seungha Yang 2024-09-08 21:01:47 +09:00 committed by GStreamer Marge Bot
parent f3589b57d2
commit e962af3064
2 changed files with 112 additions and 0 deletions

View file

@ -25,6 +25,7 @@
#include "gstd3d12-private.h" #include "gstd3d12-private.h"
#include <mutex> #include <mutex>
#include <atomic> #include <atomic>
#include <directx/d3dx12.h>
/* *INDENT-OFF* */ /* *INDENT-OFF* */
static std::recursive_mutex context_lock_; 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: * _gst_d3d12_result:
* @result: HRESULT D3D12 API return code * @result: HRESULT D3D12 API return code

View file

@ -21,6 +21,7 @@
#include <gst/gst.h> #include <gst/gst.h>
#include <gst/d3d12/gstd3d12_fwd.h> #include <gst/d3d12/gstd3d12_fwd.h>
#include <gst/video/video.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -71,6 +72,12 @@ void gst_d3d12_buffer_set_fence (GstBuffer * buffer,
guint64 fence_value, guint64 fence_value,
gboolean wait); 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 GST_D3D12_API
gboolean _gst_d3d12_result (HRESULT hr, gboolean _gst_d3d12_result (HRESULT hr,
GstD3D12Device * device, GstD3D12Device * device,