From e9cefde47935d9c6a668bb2b09860a7b10b24f18 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Thu, 30 May 2024 01:30:58 +0900 Subject: [PATCH] d3d12memory: Fix staging buffer alignment Not all GPUs can support arbitrary offset of D3D12_PLACED_SUBRESOURCE_FOOTPRINT when copying GPU memory between texture and buffer. Instead of calculating size/offset per plane, calculate the entire size and offsets at once. Part-of: --- .../gst-libs/gst/d3d12/gstd3d12bufferpool.cpp | 15 +++++++++------ .../gst-libs/gst/d3d12/gstd3d12memory.cpp | 17 +++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12bufferpool.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12bufferpool.cpp index 4fdb095bf1..b711e14de1 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12bufferpool.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12bufferpool.cpp @@ -197,14 +197,17 @@ gst_d3d12_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) D3D12_RESOURCE_STATE_COMMON, nullptr); auto num_planes = D3D12GetFormatPlaneCount (device, params->d3d12_format.dxgi_format); - for (guint i = 0; i < num_planes; i++) { - UINT64 mem_size; - device->GetCopyableFootprints (&desc[0], i, 1, 0, - &layout[i], nullptr, nullptr, &mem_size); + auto single_array_desc = desc[0]; + single_array_desc.DepthOrArraySize = 1; + + UINT64 mem_size; + device->GetCopyableFootprints (&single_array_desc, 0, num_planes, 0, + layout, nullptr, nullptr, &mem_size); + total_mem_size = mem_size; + for (guint i = 0; i < num_planes; i++) { priv->stride[i] = layout[i].Footprint.RowPitch; - priv->offset[i] = total_mem_size; - total_mem_size += mem_size; + priv->offset[i] = layout[i].Offset; } priv->alloc[0] = alloc; diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12memory.cpp b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12memory.cpp index 2f25d4ddac..c5d4d51880 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12memory.cpp +++ b/subprojects/gst-plugins-bad/gst-libs/gst/d3d12/gstd3d12memory.cpp @@ -1313,10 +1313,7 @@ gst_d3d12_allocator_alloc_wrapped (GstD3D12Allocator * allocator, mem->device = (GstD3D12Device *) gst_object_ref (device); - mem->priv->size = 0; for (guint i = 0; i < num_subresources; i++) { - UINT64 size; - /* One notable difference between D3D12/D3D11 is that, D3D12 introduced * *PLANE* slice concept. That means, Each plane of YUV format * (e.g, DXGI_FORMAT_NV12) can be accessible in D3D12 but that wasn't @@ -1333,15 +1330,15 @@ gst_d3d12_allocator_alloc_wrapped (GstD3D12Allocator * allocator, */ mem->priv->subresource_index[i] = D3D12CalcSubresource (0, array_slice, i, 1, desc.DepthOrArraySize); - - device_handle->GetCopyableFootprints (&desc, priv->subresource_index[i], - 1, 0, &priv->layout[i], nullptr, nullptr, &size); - - /* Update offset manually */ - priv->layout[i].Offset = priv->size; - priv->size += size; } + /* Then calculate staging memory size and copyable layout */ + UINT64 size; + desc.DepthOrArraySize = 1; + device_handle->GetCopyableFootprints (&desc, 0, + num_subresources, 0, priv->layout, nullptr, nullptr, &size); + priv->size = size; + priv->subresource_rect[0].left = 0; priv->subresource_rect[0].top = 0; priv->subresource_rect[0].right = (LONG) desc.Width;