Skip to content

Add DX Texture row pitch alignment for correct uploads and readbacks#1126

Merged
manon-traverse merged 3 commits intollvm:mainfrom
Traverse-Research:texture-row-pitch-alignment
May 4, 2026
Merged

Add DX Texture row pitch alignment for correct uploads and readbacks#1126
manon-traverse merged 3 commits intollvm:mainfrom
Traverse-Research:texture-row-pitch-alignment

Conversation

@EmilioLaiso
Copy link
Copy Markdown
Contributor

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 RowPitch in a placed footprint to be a multiple of D3D12_TEXTURE_DATA_PITCH_ALIGNMENT (256 bytes).

@manon-traverse manon-traverse changed the title DX Texture row pitch alignment Add DX Texture row pitch alignment for correct uploads and readbacks Apr 30, 2026
Comment thread lib/API/DX/Device.cpp
Comment on lines +150 to +153
static uint64_t getAlignedTextureBufferSize(const CPUBuffer &B) {
return uint64_t(B.OutputProps.Height) *
getAlignedTexturePitch(B.OutputProps.Width, B.getElementSize());
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)

Comment thread lib/API/DX/Device.cpp
BufDesc.Location = MemoryLocation::GpuToCpu;
auto BufOrErr = createBuffer("RTReadback", BufDesc, OutBuf.size());
auto BufOrErr = createBuffer("RTReadback", BufDesc,
getAlignedTextureBufferSize(OutBuf));
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for sanity-checking, this is effectively TotalBytes which GetCopyableFootprints() would have otherwise returned?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above comment, iirc GetCopyableFootprints returns the unpadded last row.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, and we can use the unpadded row size too right? That's what the updated function returns after my request?

@manon-traverse manon-traverse merged commit 8afabf9 into llvm:main May 4, 2026
21 of 22 checks passed
@MarijnS95 MarijnS95 deleted the texture-row-pitch-alignment branch May 5, 2026 08:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants