[pixel shader fail] float4 func(); float4 main() : sv_target { return func(); } % It's legal to call an undefined function in unused code, though. [pixel shader] float4 func(); float4 unused() { return func(); } float4 main() : sv_target { return 0; } [pixel shader fail] void func(inout float o) { o += 0.1; } float4 main() : sv_target { float x = 0; func(x + 1); return 0; } [pixel shader fail] void func(inout float2 o) { o += 0.1; } float4 main() : sv_target { float2 x = 0; func(x.yy); return 0; } [pixel shader fail] void func(out float o) { o = 0.1; } float4 main() : sv_target { const float x = 0; func(x); return x; } [pixel shader fail] void func(inout float o) { } float4 main() : sv_target { const float x = 0; func(x); return x; } [pixel shader fail] void func() { } float4 main() : sv_target { return func(); } [pixel shader fail(sm<6)] void foo() { } void bar() { return foo(); } float4 main() : sv_target { bar(); return 0; } % The function must have been at least declared before calling it. It may have % been declared with a different but compatible type, though. [pixel shader fail] float4 main() : sv_target { func(); return 0; } void func() { } [pixel shader] void func(); float4 main() : sv_target { func(); return 0; } void func() { } [pixel shader fail] void func(float arg); float4 main() : sv_target { func(); return 0; } void func() { } [pixel shader] /* This is something of an internal test: we need to make sure that we use the * correct variables for a function's arguments and returns regardless of * whether it's been defined yet. * * Also, make sure that we can handle the case where the argument names differ. */ float2 concat(float x, float y); float2 func(void) { return concat(0.1, 0.2); } float2 concat(float a, float b) { return float2(a, b); } float4 main() : sv_target { return float4(func(), concat(0.3, 0.4)); } [test] todo(glsl) draw quad probe all rgba (0.1, 0.2, 0.3, 0.4) [pixel shader] float func(in float a, out float b, inout float c) { c -= 0.2; b = a * 2; return a + 0.2; } float4 main() : sv_target { float x[2], ret; x[0] = 0.1; x[1] = 0.9; ret = func(0.3, x[0], x[1]); return float4(ret, x[0], x[1], 0); } [test] todo(glsl) draw quad probe all rgba (0.5, 0.6, 0.7, 0) [pixel shader] void func(in float a, inout float2 b) { b.y += 0.1; b *= a; } float4 main() : sv_target { float3 q = float3(0.1, 0.2, 0.3); func(3.0, q.zx); func(0.5, q.yz); return float4(q, 0); } [test] todo(glsl) draw quad probe all rgba (0.6, 0.1, 0.5, 0) % Recursion is forbidden. [pixel shader notimpl(sm<6) fail(sm>=6)] void bar(); void foo() { bar(); } void bar() { foo(); } float4 main() : sv_target { foo(); return 0; } [pixel shader notimpl(sm<6) fail(sm>=6)] % Even trivially finite recursion is forbidden. void func(bool x) { if (x) func(false); } float4 main() : sv_target { func(true); return 0; } [pixel shader] float func(float a) { return a + 1; } float4 main() : sv_target { return float4(func(1.0), func(2.0), func(5.0), func(6.0)); } [test] todo(glsl) draw quad probe all rgba (2.0, 3.0, 6.0, 7.0) [pixel shader] float func(float a) { return a + 1; } float4 main() : sv_target { float4 a = {func(1.0), func(2.0), func(5.0), func(6.0)}; return a; } [test] todo(glsl) draw quad probe all rgba (2.0, 3.0, 6.0, 7.0) % Inline modifier [pixel shader] inline float func(float a) { return a + 1; } float4 main() : sv_target { float4 a = {func(1.0), func(2.0), func(5.0), func(6.0)}; return a; } [test] todo(glsl) draw quad probe all rgba (2.0, 3.0, 6.0, 7.0) % Inline modifier used on entry point [pixel shader fail(sm>=6)] float func(float a) { return a + 1; } inline float4 main() : sv_target { float4 a = {func(1.0), func(2.0), func(5.0), func(6.0)}; return a; } [test] todo(glsl) draw quad probe all rgba (2.0, 3.0, 6.0, 7.0)