[pixel shader] // Test empty constant buffer. cbuffer Constants : register(b1) { }; float4 foo; float4 main() : sv_target { return foo; } [test] uniform 0 float4 1.0 2.0 3.0 4.0 draw quad probe all rgba (1.0, 2.0, 3.0, 4.0) % SM1 buffer offset allocation follows different rules than SM4. % Those would have to be tested separately. [require] shader model >= 4.0 [pixel shader fail] cbuffer buffer { float4 a : packoffset(c1invalid_extra_chars); } float4 main() : sv_target { return 0; } % Respect register boundaries [pixel shader] cbuffer buffer { float2 a; float2 b; float2 c; float3 d; } float4 main() : sv_target { return float4(a.x, b.x, c.x, d.x); } [test] uniform 0 float4 0.0 1.0 2.0 3.0 uniform 4 float4 4.0 5.0 6.0 7.0 uniform 8 float4 8.0 9.0 10.0 11.0 uniform 12 float4 12.0 13.0 14.0 15.0 draw quad probe all rgba (0.0, 2.0, 4.0, 8.0) [pixel shader] cbuffer buffer { float a; float b[2]; float c; } float4 main() : sv_target { return float4(a, b[0], b[1], c); } [test] uniform 0 float4 0.0 1.0 2.0 3.0 uniform 4 float4 4.0 5.0 6.0 7.0 uniform 8 float4 8.0 9.0 10.0 11.0 draw quad probe all rgba (0.0, 4.0, 8.0, 9.0) [pixel shader] cbuffer buffer { float a; struct { float b; float c; } p; float d; } float4 main() : sv_target { return float4(a, p.b, p.c, d); } [test] uniform 0 float4 0.0 1.0 2.0 3.0 uniform 4 float4 4.0 5.0 6.0 7.0 uniform 8 float4 8.0 9.0 10.0 11.0 uniform 12 float4 12.0 13.0 14.0 15.0 draw quad probe all rgba (0.0, 4.0, 5.0, 6.0) [pixel shader fail todo] // Elements cannot overlap if buffer is used. cbuffer buffer { float c : packoffset(c0); float4 a[2] : packoffset(c1); float4 b[2] : packoffset(c2); } float4 main() : sv_target { return c; } [pixel shader] // Elements can overlap if buffer is not used. cbuffer buffer { float4 a[2] : packoffset(c1); float4 b[2] : packoffset(c2); } float4 main() : sv_target { return 0; } [pixel shader] cbuffer buffer { float4 a : packoffset(c1); float4 b : packoffset(c2); } float4 main() : sv_target { return 100 * a + b; } [test] uniform 0 float4 1.0 2.0 3.0 4.0 uniform 4 float4 5.0 6.0 7.0 8.0 uniform 8 float4 9.0 10.0 11.0 12.0 draw quad probe all rgba (509, 610, 711, 812) [pixel shader] struct apple { float2 a; float b; float4 c; }; cbuffer buffer { float4 foo : packoffset(c3); struct apple bar : packoffset(c1); } float4 main() : sv_target { return 1000 * foo + 100 * float4(bar.a, 0, 0) + 10 * float4(bar.b, 0, 0, 0) + bar.c; } [test] uniform 0 float4 0.0 1.0 2.0 3.0 uniform 4 float4 4.0 5.0 6.0 7.0 uniform 8 float4 8.0 9.0 10.0 11.0 uniform 12 float4 12.0 13.0 14.0 15.0 draw quad probe all rgba (12468.0, 13509.0, 14010.0, 15011.0) [pixel shader] cbuffer buffer { float2 c : packoffset(c0.y); } float4 main() : sv_target { return float4(c, c); } [test] uniform 0 float4 1.0 2.0 3.0 4.0 draw quad probe all rgba (2.0, 3.0, 2.0, 3.0) [pixel shader fail] // Elements must respect register boundaries. cbuffer buffer { float4 c : packoffset(c0.z); } float4 main() : sv_target { return 0; } [pixel shader fail] // Matrices must be aligned. cbuffer buffer { float1x1 m : packoffset(c0.y); } float4 main() : sv_target { return 0; } [pixel shader fail] // Arrays must be aligned. cbuffer buffer { float a[1] : packoffset(c0.y); } float4 main() : sv_target { return 0; } [pixel shader fail] // Structs must be aligned. struct apple { float p; }; cbuffer buffer { struct apple a : packoffset(c0.y); } float4 main() : sv_target { return 0; } [pixel shader fail] // Invalid offset on unused buffer. cbuffer buffer { float3 a : packoffset(c0.z); } float4 main() : sv_target { return 0; } [pixel shader fail] // Invalid offset on unused variable. cbuffer buffer { float a : packoffset(c0); float3 b : packoffset(c0.z); } float4 main() : sv_target { return a; } [pixel shader] cbuffer buffer { float4 a : packoffset(c1); float1 b : packoffset(c0); float1 c : packoffset(c0.y); } float4 main() : sv_target { return 100 * a + 10 * b + c; } [test] uniform 0 float 1.0 uniform 1 float 2.0 uniform 4 float4 5.0 6.0 7.0 8.0 draw quad probe all rgba (512.0, 612.0, 712.0, 812.0) [pixel shader fail todo] // packoffset cannot be used unless all elements use it. cbuffer buffer { float4 a : packoffset(c0); float4 b; } float4 main() : sv_target { return a + b; } [pixel shader] cbuffer buffer { float2 c : packoffset(c0.b); } float4 main() : sv_target { return float4(c, c); } [test] uniform 0 float4 1.0 2.0 3.0 4.0 draw quad probe all rgba (3.0, 4.0, 3.0, 4.0) [pixel shader fail] cbuffer buffer { float2 c : packoffset(c0.xy); } float4 main() : sv_target { return 0; } [pixel shader fail] cbuffer buffer { float4x4 mat : packoffset(c0._m00); } float4 main() : sv_target { return 0; } [pixel shader fail] cbuffer buffer { float4 a : packoffset(c0._m00); } float4 main() : sv_target { return 0; } [pixel shader fail] cbuffer buffer { float2 c : packoffset(c0.xz); } float4 main() : sv_target { return 0; } % packoffset cannot be used outside a constant buffer. [pixel shader fail] float4 a : packoffset(c0); float4 main() : sv_target { return 0; } [pixel shader fail] float4 foo(float4 a : packoffset(c0)) { return a; } float4 main() : sv_target { return 0; } [pixel shader fail] float4 foo(float4 a) : packoffset(c0) { return a; } float4 main() : sv_target { return 0; } [pixel shader fail] struct apple { float4 a : packoffset(c0); }; cbuffer buffer { struct apple a; } float4 main() : sv_target { return 0; } [pixel shader fail] cbuffer buffer { struct { float4 a : packoffset(c0); } s; } float4 main() : sv_target { return 0; }