% Test how semantics are determined when spread across the entry point's % definition and its declarations. [vertex shader] void main(float4 pos : position, out float tex : texcoord, out float4 out_pos : sv_position) { tex = 0.2; out_pos = pos; } [pixel shader fail] float4 main(float tex : texcoord) : sv_target; float4 main(float tex) { return tex; } [pixel shader fail] float4 main(float tex) { return tex; } float4 main(float tex : texcoord) : sv_target; [pixel shader] float4 main(float tex : bogus) : bogus; float4 main(float tex : texcoord) : sv_target { return tex; } [test] todo(msl) draw quad probe (0, 0) rgba (0.2, 0.2, 0.2, 0.2) [pixel shader] float4 main(float tex : texcoord) : sv_target { return tex; } float4 main(float tex : bogus) : bogus; [test] todo(msl) draw quad probe (0, 0) rgba (0.2, 0.2, 0.2, 0.2) [vertex shader] void main(float4 pos : position, out float4 tex[4] : texcoord, out float4 out_pos : sv_position) { tex[0] = float4(10.0, 11.0, 12.0, 13.0); tex[1] = float4(20.0, 21.0, 22.0, 23.0); tex[2] = float4(30.0, 31.0, 32.0, 33.0); tex[3] = float4(40.0, 41.0, 42.0, 43.0); out_pos = pos; } % Array parameters of non-struct elements must have a semantic. [pixel shader fail] float4 main(in float2 arr[2]) : sv_target { return 0.0; } % Array elements with a semantic get successive indexes. [pixel shader] struct apple { float3 tp[4] : TEXCOORD0; }; float4 main(in apple a) : sv_target { return float4(a.tp[0].x, a.tp[1].x, a.tp[2].x, a.tp[3].x); } [test] todo(msl) draw quad probe (0, 0) rgba (10.0, 20.0, 30.0, 40.0) % Arrays of matrices get successive indexes. [pixel shader] struct apple { float4x2 tp[2] : TEXCOORD0; }; float4 main(in apple a) : sv_target { return float4(a.tp[0][0].x, a.tp[0][1].x, a.tp[1][0].x, a.tp[1][1].x); } [test] todo(msl) draw quad probe (0, 0) rgba (10.0, 11.0, 30.0, 31.0) % dxcompiler emits correct array addressing. [require] shader model < 6.0 % Arrays (even multi-dimensional) of struct elements are allowed. The fields in the different struct % elements get the same indexes. [pixel shader] struct apple { float4 tc0 : TEXCOORD0; float4 tc1 : TEXCOORD1; }; float4 main(in apple aps[2][2]) : sv_target { return float4(aps[0][0].tc0.x, aps[1][1].tc0.x, aps[0][0].tc1.x, aps[1][1].tc1.x); } [test] todo(msl) draw quad probe (0, 0) rgba (10.0, 10.0, 20.0, 20.0) [pixel shader] struct apple { float4 tc0 : TEXCOORD0; }; struct banana { apple apl; float4 tc1 : TEXCOORD1; }; float4 main(in banana bans[2]) : sv_target { return float4(bans[0].apl.tc0.xy, bans[1].tc1.xy); } [test] todo(msl) draw quad todo(sm>=6) probe (0, 0) rgba (10.0, 11.0, 20.0, 21.0) [require] % reset requirements [pixel shader fail] struct apple { float2 miss; // missing semantic. }; struct banana { apple apl[2]; float4 arb : UNUSED; }; float4 main(in banana bans[2]) : sv_target { return 0.0; } [vertex shader fail] struct apple { float2 miss; // missing semantic. }; struct banana { apple apl[2]; float4 arb : UNUSED; }; void main(out banana bans[2]) { return 0.0; } [vertex shader] struct apple { float4 tex[2] : TEXCOORD0; }; void main(float4 pos : position, out apple apl, out float4 out_pos : sv_position) { apl.tex[0] = float4(1, 2, 3, 4); apl.tex[1] = float4(10, 20, 30, 40); out_pos = pos; } [pixel shader] float4 main(in float4 tex0 : TEXCOORD0, in float4 tex1 : TEXCOORD1) : sv_target { return float4(tex0.xy, tex1.xy); } [test] todo(msl) draw quad probe (0, 0) rgba (1.0, 2.0, 10.0, 20.0) % Output semantics cannot be mapped to more than one value. [vertex shader fail(sm<6)] struct apple { float2 tex : TEXCOORD0; }; void main(float4 pos : position, out apple apls[2], out float4 out_pos : sv_position) { apls[0].tex = float2(1, 2); apls[1].tex = float2(3, 4); out_pos = pos; } [vertex shader fail] struct apple { float2 f : SEMANTIC; }; void main(float4 pos : position, out apple a, out apple b, out float4 out_pos : sv_position) { a.f = float2(1, 2); b.f = float2(3, 4); out_pos = pos; } % Semantic names are case-insensitive. [vertex shader fail] void main(float4 pos : position, out float2 a : sem0, out float2 b : SEM, out float4 out_pos : sv_position) { a = float2(1, 2); b = float2(3, 4); out_pos = pos; } [vertex shader] void main(float4 pos : position, out float4 tex[4] : texcoord, out float4 out_pos : sv_position) { tex[0] = float4(10.0, 11.0, 12.0, 13.0); tex[1] = float4(20.0, 21.0, 22.0, 23.0); tex[2] = float4(30.0, 31.0, 32.0, 33.0); tex[3] = float4(40.0, 41.0, 42.0, 43.0); out_pos = pos; } % Arguments with the same semantic aren't aliased. [pixel shader fail(sm>=6)] float4 main(in float4 t1 : TEXCOORD0, in float4 t2 : TEXCOORD0) : sv_target { t1 = 99; return float4(t1.xy, t2.xy); } [test] todo(msl) draw quad todo(sm>=6) probe (0, 0) rgba (99.0, 99.0, 10.0, 11.0) % Different indexes of the same semantic can have different types. [pixel shader] float4 main(in float4 a : TEXCOORD0, in float3 b : TEXCOORD1) : sv_target { return float4(a.xy, b.xy); } [test] todo(msl) draw quad probe (0, 0) rgba (10.0, 11.0, 20.0, 21.0) % In SM4, duplicated input semantics can only have different types if they have the same layout and % register types. SM1 is permissive in this regard. [pixel shader fail(sm>=6)] float4 main(in float2 a : TEXCOORD0, in half2 b : TEXCOORD0, in float2x1 c: TEXCOORD0) : sv_target { return 0.0; } [pixel shader fail(sm>=6)] float4 main(in uint2 a : TEXCOORD0, in int2 b : TEXCOORD0, in int2x1 c : TEXCOORD0, in bool2 d : TEXCOORD0) : sv_target { return 0.0; } [require] shader model >= 4.0 [pixel shader fail] float4 main(in float2 a : TEXCOORD0, in float3 b : TEXCOORD0) : sv_target { return 0.0; } [pixel shader fail] float4 main(in float2 a : TEXCOORD0, in int2 b : TEXCOORD0) : sv_target { return 0.0; } % For some reason, vectors from row_major matrices are not considered as having the same layout as % regular vectors. [pixel shader fail todo] float4 main(in float2 a : TEXCOORD0, row_major float1x2 b : TEXCOORD0) : sv_target { return 0.0; } [pixel shader fail] float4 main(in float2 a : TEXCOORD0, row_major float2x1 b : TEXCOORD0) : sv_target { return 0.0; } [pixel shader fail todo] float4 main(in float4 a : TEXCOORD0, row_major float1x4 b : TEXCOORD0) : sv_target { return 0.0; }