Why do these DirectXMath functions seem like they return column-major matrics?

I know these questions have been asked a million times in various formats, but I'm getting weirdly skeptical about some of the row-major vs. column-major claims about the DirectXMath library.

If I run the following code to get a translation matrix for example:

DirectX::XMMATRIX a = DirectX::XMMatrixTranslation(1.0f, 1.0f, -1.0f));


I would expect the memory layout to look like the following (with rN indicating some row, but all the numbers contiguously in memory):

r1: 1.0   0.0   0.0   1.0      r2: 0.0   1.0   0.0   1.0     r3: 0.0   0.0   1.0  -1.0     r4: 0.0   0.0   0.0   1.0


This would correspond to the following matrix (in standard notation) where each row is stored as a contiguous array:

1.0   0.0   0.0   1.0
0.0   1.0   0.0   1.0
0.0   0.0   1.0  -1.0
0.0   0.0   0.0   1.0


Except when I look at the memory, it's the transpose of the above (i.e. the last array in memory is the last column above) which I'm to understand is "column-major" order. So, in memory, what I'm actually getting is this:

r1: 1.0   0.0   0.0   0.0     r2: 0.0   1.0   0.0   0.0     r3: 0.0   0.0   1.0   0.0     r4: 1.0   1.0   -1.0   1.0


This leaves me thoroughly confused with all the commentary and documentation around DirectXMath matrices needing to be transposed before putting them into HLSL constant buffers (of which I'm using the default column-major order). Everything states that DirectXMath matrices are stored in row-major order, but when I actually look at the memory (either as an XMMATRIX or a more direct XMFLOAT4X4) I find myself staring at a translation matrix that looks like it's been stored in column-major order.

So my confusion then lies in the fact that my transformations actually work when I don't transpose the matrices prior to putting them into the constant buffer.

Am I missing something here?

You posted a column-major version of the translation matrix for (1,1,-1):

1.0   0.0   0.0   1.0
0.0   1.0   0.0   1.0
0.0   0.0   1.0  -1.0
0.0   0.0   0.0   1.0


The row-major version is:

1.0   0.0   0.0   0.0 [r0]
0.0   1.0   0.0   0.0 [r1]
0.0   0.0   1.0   0.0 [r2]
1.0   1.0  -1.0   1.0 [r3]


Which is precisely what you see in XMMATRIX.

As noted in the DirectXMath Programmer's Guide:

DirectXMath uses row-major matrices, row vectors, and pre-multiplication. Handedness is determined by which function version is used (RH vs. LH), otherwise the function works with either left-handed or right-handed view coordinates.

For reference, Direct3D has historically used left-handed coordinate system, row-major matrices, row vectors, and pre-multiplication. Modern Direct3D does not have a strong requirement for left vs. right-handed coordinates, and typically HLSL shaders default to consuming column-major matrices. See HLSL Matrix Ordering for details.

• XMMATRIX.r[3] contains the translation, i.e. the 4th row's x, y, and z. See Wikipedia: "In a row-major order, the consecutive elements of a row reside next to each other, whereas the same holds true for consecutive elements of a column in a column-major order.". This blog post might also help. – Chuck Walbourn Feb 2 '18 at 19:23