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
This commit is contained in:
Jake Turner committed 2024-01-22 09:39:22 +00:00
1 parent e18ea02a2b
commit 7b75e05b2c
1 file changed
+8 -7
@@ -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);