Add DX Texture row pitch alignment for correct uploads and readbacks#1126
Conversation
| static uint64_t getAlignedTextureBufferSize(const CPUBuffer &B) { | ||
| return uint64_t(B.OutputProps.Height) * | ||
| getAlignedTexturePitch(B.OutputProps.Width, B.getElementSize()); | ||
| } |
There was a problem hiding this comment.
I remember complicated maths in our own backend, where we don't apply this alignment to the last line.
Hopefully that was "just" a minor memory-usage optimization, and not something that's required under the hood?
There was a problem hiding this comment.
Dx12 only requires RowPitch to be 256-byte aligned. The padding bytes that round each row's data up to that pitch only exist so the next row starts at an aligned offset. The last row has no "next row," so its trailing padding is unused. I updated the function to reflect this (not padding last row)
| BufDesc.Location = MemoryLocation::GpuToCpu; | ||
| auto BufOrErr = createBuffer("RTReadback", BufDesc, OutBuf.size()); | ||
| auto BufOrErr = createBuffer("RTReadback", BufDesc, | ||
| getAlignedTextureBufferSize(OutBuf)); |
There was a problem hiding this comment.
Just for sanity-checking, this is effectively TotalBytes which GetCopyableFootprints() would have otherwise returned?
There was a problem hiding this comment.
See above comment, iirc GetCopyableFootprints returns the unpadded last row.
There was a problem hiding this comment.
Yeah, and we can use the unpadded row size too right? That's what the updated function returns after my request?
When writing a test outputting to a 2x2 texture, I noticed that -on DX- the readback results contained wrong values. This happens because D3D12 spec requires
RowPitchin a placed footprint to be a multiple ofD3D12_TEXTURE_DATA_PITCH_ALIGNMENT(256 bytes).