[RW]StructuredBuffer<matrix> ignores orientation
Repro:
typedef row_major int2x2 rmi22;
RWStructuredBuffer<rmi22> buf;
void main() { buf[0] = int2x2(11, 12, 21, 22); }
DXC generated code (packing orientation ignored):
call void @dx.op.bufferStore.i32(i32 69, %dx.types.Handle %buf_UAV_structbuf, i32 0, i32 0, i32 11, i32 21, i32 12, i32 22, i8 15)
FXC generated code (packing orientation taken into account):
store_structured u0.xyzw, l(0), l(0), l(11,12,21,22)
The problem is that RWStructuredBuffer<rmi22> causes a template specialization to be created, which calls Sema::CheckTemplateTypeArgument for rmi22 and uses getCanonicalType to get the final type. Hence the instantiated type is RWStructuredBuffer<matrix<int, 2, 2>>, whose operator[](int index) returns an unattributed matrix<int, 2, 2>&.
Note FXC has a bug here: it will not accept the syntax RWStructuredBuffer<row_major int2x2> and will not honor /Zpr nor #pragma pack_matrix(row_major) on RWStructuredBuffer<int2x2>, always defaulting to column_major. The only way to get it to store in row-major format is using the typedef method above.
This is similar to, but not the same as #1788 , where the matrix is a field of a struct used as a structured buffer.
Hmm, this is very likely the same bug as #1722 , since unorm/snorm are also attributed types which would disappear when used as template arguments.
Related #2499, #3423