[pixel shader] #pragma pack_matrix(row_major) uniform float2x2 r; #pragma pack_matrix(column_major) uniform float2x2 c; float4 main() : sv_target { float4 ret; ret.xy = mul(r, float2(0.5, 0.6)); ret.zw = mul(c, float2(0.5, 0.6)); return ret; } [test] uniform 0 float4 0.1 0.2 0.0 0.0 uniform 4 float4 0.3 0.4 0.0 0.0 uniform 8 float4 0.1 0.3 0.0 0.0 uniform 12 float4 0.2 0.4 0.0 0.0 draw quad probe all rgba (0.17, 0.39, 0.17, 0.39) 1 %% Test with a struct. [pixel shader] #pragma pack_matrix(row_major) struct apple { float2x2 m; }; #pragma pack_matrix(column_major) uniform struct apple a; float4 main() : sv_target { return float4(a.m[0], a.m[1]); } [test] uniform 0 float4 0.1 0.2 0.0 0.0 uniform 4 float4 0.3 0.4 0.0 0.0 draw quad probe all rgba (0.1, 0.2, 0.3, 0.4) %% Test with an array. [pixel shader] #pragma pack_matrix(row_major) uniform float2x2 m[2]; #pragma pack_matrix(column_major) float4 main() : sv_target { return float4(m[1][0], m[1][1]); } [test] uniform 0 float4 0.0 0.0 0.0 0.0 uniform 4 float4 0.0 0.0 0.0 0.0 uniform 8 float4 0.5 0.6 0.0 0.0 uniform 12 float4 0.7 0.8 0.0 0.0 draw quad probe all rgba (0.5, 0.6, 0.7, 0.8) % The documentation claims these strings are subject to macro expansion. % They are not. [pixel shader] #define KEY pack_matrix #pragma KEY(row_major) #define VALUE row_major #pragma pack_matrix(VALUE) #define PRAGMA pack_matrix(row_major) #pragma PRAGMA uniform float2x2 r; float4 main() : sv_target { float4 ret; ret.xy = mul(r, float2(0.5, 0.6)); ret.zw = 0.5; return ret; } [test] uniform 0 float4 0.1 0.2 0.0 0.0 uniform 4 float4 0.3 0.4 0.0 0.0 draw quad probe all rgba (0.23, 0.34, 0.5, 0.5) 1 % The majority that applies to a typedef is the latent majority at the time % that typedef was declared. [pixel shader] #pragma pack_matrix(row_major) typedef float2x2 mat_t; #pragma pack_matrix(column_major) uniform mat_t m; float4 main() : sv_target { return float4(m[0], m[1]); } [test] uniform 0 float4 0.1 0.2 0.0 0.0 uniform 4 float4 0.3 0.4 0.0 0.0 draw quad probe all rgba (0.1, 0.2, 0.3, 0.4) % In fact, it's illegal to specify a contradictory majority. [pixel shader fail] #pragma pack_matrix(row_major) typedef float2x2 mat_t; uniform column_major mat_t m; float4 main() : sv_target { return 0; } % This applies to arrays as well. Note that struct fields already have latent % majority applied (even if there have been no pragmas, as shown below), so the % question of typedefs is moot there. [pixel shader] #pragma pack_matrix(row_major) typedef float2x2 myarray_t[2]; #pragma pack_matrix(column_major) uniform myarray_t a; float4 main() : sv_target { return float4(a[0][0], a[1][1]); } [test] uniform 0 float4 0.3 0.4 0.0 0.0 uniform 4 float4 0.0 0.0 0.0 0.0 uniform 8 float4 0.0 0.0 0.0 0.0 uniform 12 float4 0.5 0.6 0.0 0.0 draw quad probe all rgba (0.3, 0.4, 0.5, 0.6) % However, if no pack_matrix directive has been used yet, a typedef has no % defined majority, and the majority can be overwritten, including by a % subsequent pragma. [pixel shader] typedef float2x2 mat_t; #pragma pack_matrix(row_major) uniform mat_t m; uniform row_major mat_t r; uniform column_major mat_t c; float4 main() : sv_target { return float4(m[0], m[1]); } [test] uniform 0 float4 0.1 0.2 0.0 0.0 uniform 4 float4 0.3 0.4 0.0 0.0 draw quad probe all rgba (0.1, 0.2, 0.3, 0.4) % This does not apply recursively to struct or array members, however. Members % defined while there is no latent majority are always column-major, even if % the type is later used after a pack_matrix(row_major) directive. % Note that the majority of the struct or array type cannot itself be % overwritten with modifiers; those are only valid on matrix types. [pixel shader] struct apple { float2x2 m; }; #pragma pack_matrix(row_major) typedef struct apple apple_t; uniform apple_t a; float4 main() : sv_target { return float4(a.m[0], a.m[1]); } [test] uniform 0 float4 0.2 0.4 0.0 0.0 uniform 4 float4 0.3 0.5 0.0 0.0 draw quad probe all rgba (0.2, 0.3, 0.4, 0.5) [pixel shader] typedef float2x2 myarray_t[2]; #pragma pack_matrix(row_major) typedef myarray_t myarray2_t; uniform myarray2_t a; float4 main() : sv_target { return float4(a[0][0], a[1][1]); } [test] uniform 0 float4 0.3 0.0 0.0 0.0 uniform 4 float4 0.4 0.0 0.0 0.0 uniform 8 float4 0.0 0.5 0.0 0.0 uniform 12 float4 0.0 0.6 0.0 0.0 draw quad probe all rgba (0.3, 0.4, 0.5, 0.6)