From 7b75e05b2c698f97980c42bfc2c8f09e189cd912 Mon Sep 17 00:00:00 2001 From: Jake Turner Date: Sat, 13 Jan 2024 08:55:33 +0000 Subject: [PATCH] D3D12 Pixel History fix copy from texture to buffer Use D3D12_PLACED_SUBRESOURCE_FOOTPRINT Offset parameter to get to within 16KB of the destination buffer byte offset. Set the copy texture footprint to be a 1D Texture with a width to be equal to the remaining byte offset / pixel_byte_size + 1. Use a destination X of the remaining byte offset / pixel_byte_size --- renderdoc/driver/d3d12/d3d12_pixelhistory.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/renderdoc/driver/d3d12/d3d12_pixelhistory.cpp b/renderdoc/driver/d3d12/d3d12_pixelhistory.cpp index 2fe97dd22..4c5bbfb5b 100644 --- a/renderdoc/driver/d3d12/d3d12_pixelhistory.cpp +++ b/renderdoc/driver/d3d12/d3d12_pixelhistory.cpp @@ -642,16 +642,19 @@ protected: // Copy into a buffer, but treat the footprint as the same format as the target image uint32_t elementSize = GetByteSize(0, 0, 0, p.copyFormat, 0); + // Use Offset to get to the nearest 16KB + UINT64 footprintOffset = (offset >> 14) << 14; + UINT64 offsetRemaider = offset - footprintOffset; + UINT dstX = (UINT)(offsetRemaider / elementSize); dst.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; dst.pResource = m_CallbackInfo.dstBuffer; - dst.PlacedFootprint.Offset = 0; - dst.PlacedFootprint.Footprint.Width = - (UINT)m_CallbackInfo.dstBuffer->GetDesc().Width / elementSize; + dst.PlacedFootprint.Offset = footprintOffset; + dst.PlacedFootprint.Footprint.Width = dstX + 1; dst.PlacedFootprint.Footprint.Height = 1; dst.PlacedFootprint.Footprint.Depth = 1; dst.PlacedFootprint.Footprint.Format = p.copyFormat; - dst.PlacedFootprint.Footprint.RowPitch = (UINT)m_CallbackInfo.dstBuffer->GetDesc().Width; + dst.PlacedFootprint.Footprint.RowPitch = dst.PlacedFootprint.Footprint.Width * elementSize; D3D12_BOX srcBox = {}; srcBox.left = p.x; @@ -661,10 +664,8 @@ protected: srcBox.front = 0; srcBox.back = 1; - // We need to apply the offset here (measured in number of elements) rather than using - // PlacedFootprint.Offset (measured in bytes) because the latter must be a multiple of 512 RDCASSERT((offset % elementSize) == 0); - cmd->CopyTextureRegion(&dst, (UINT)(offset / elementSize), 0, 0, &src, &srcBox); + cmd->CopyTextureRegion(&dst, dstX, 0, 0, &src, &srcBox); std::swap(barrier.Transition.StateBefore, barrier.Transition.StateAfter); cmd->ResourceBarrier(1, &barrier);