From 5118e657b68b354e9795b5cacc090da688f7f10f 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: --- .../sys/d3d12/gstd3d12bufferpool.cpp | 15 +++++++++------ .../sys/d3d12/gstd3d12memory.cpp | 17 +++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12bufferpool.cpp b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12bufferpool.cpp index 81db0ab3c0..e2d0e5aaca 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12bufferpool.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12bufferpool.cpp @@ -194,14 +194,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/sys/d3d12/gstd3d12memory.cpp b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12memory.cpp index ad9c4efced..05ce8d3d45 100644 --- a/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12memory.cpp +++ b/subprojects/gst-plugins-bad/sys/d3d12/gstd3d12memory.cpp @@ -733,10 +733,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 @@ -753,15 +750,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;