[require] % The ternary operator works differently in sm6. See sm6-ternary.shader_test. shader model < 6.0 [pixel shader] uniform float4 x; float4 main() : sv_target { return x.x ? x : x - 1; } [test] uniform 0 float4 2.0 3.0 4.0 5.0 draw quad probe (0, 0) rgba (2.0, 3.0, 4.0, 5.0) uniform 0 float4 0.0 10.0 11.0 12.0 draw quad probe (0, 0) rgba (-1.0, 9.0, 10.0, 11.0) [pixel shader] uniform float4 x; float4 main() : sv_target { float4 ret; ret.x = x.x ? x.x : 1; ret.y = x.y ? 2 : x.y; ret.z = ret.w = 0.0; return ret; } [test] uniform 0 float4 1.1 3.0 4.0 5.0 draw quad probe (0, 0) rgba (1.1, 2.0, 0.0, 0.0) [pixel shader] float4 f; float4 main() : sv_target { float f1 = 0.1, f2 = 0.2, f3; f3 = f.x ? (f1 = 0.5) + 0.2 : (f2 = 0.6); return float4(f1, f2, f3, 0.0); } [test] uniform 0 float4 1.0 0.0 0.0 0.0 draw quad probe (0, 0) rgba (0.5, 0.6, 0.7, 0.0) [pixel shader] float4 x, y, z; float4 main() : sv_target { return x ? y : z; } [test] uniform 0 float4 0.0 1.0 0.0 -3.0 uniform 4 float4 1.0 2.0 3.0 4.0 uniform 8 float4 5.0 6.0 7.0 8.0 draw quad probe (0, 0) rgba (5.0, 2.0, 7.0, 4.0) [pixel shader] int4 x, y, z; float4 main() : sv_target { return x ? y : z; } [test] if(sm<4) uniform 0 float4 0.0 1.0 0.0 -3.0 if(sm<4) uniform 4 float4 1.0 2.0 3.0 4.0 if(sm<4) uniform 8 float4 5.0 6.0 7.0 8.0 if(sm>=4) uniform 0 int4 0 1 0 -3 if(sm>=4) uniform 4 int4 1 2 3 4 if(sm>=4) uniform 8 int4 5 6 7 8 draw quad probe (0, 0) f32(5.0, 2.0, 7.0, 4.0) [pixel shader] uint4 x, y, z; float4 main() : sv_target { return x ? y : z; } [test] if(sm<4) uniform 0 float4 0.0 1.0 0.0 3.0 if(sm<4) uniform 4 float4 1.0 2.0 3.0 4.0 if(sm<4) uniform 8 float4 5.0 6.0 7.0 8.0 if(sm>=4) uniform 0 uint4 0 1 0 3 if(sm>=4) uniform 4 uint4 1 2 3 4 if(sm>=4) uniform 8 uint4 5 6 7 8 draw quad probe (0, 0) f32(5.0, 2.0, 7.0, 4.0) % The usual type conversion is applied to the first and second expression, as % long as they are numeric. [pixel shader fail] uniform float2x4 a; uniform float3x2 b; float4 main() : sv_target { 0 ? a : b; return 0; } [pixel shader] static float3x3 a = {0, 1, 2, 3, 4, 5, 6, 7, 8}; static float2x2 b = {.1, .2, .3, .4}; float4 main() : sv_target { return float4(1 ? a : b); } [test] draw quad probe (0, 0) rgba (0.0, 1.0, 3.0, 4.0) [pixel shader] static float3 a = {0, 1, 2}; static float4 b = {5, 6, 7, 8}; float4 main() : sv_target { return float4(0 ? a : b, 1.0); } [test] draw quad probe (0, 0) rgba (5.0, 6.0, 7.0, 1.0) % More restrictions are placed on the type of the first (condition) operand, % relative to the common type computed from the other two (result). Either: % * the class and dimensions must match exactly; % * the condition operand is scalar; % * the result operands are scalar; % * one is a typeN and the other is a type1xN [pixel shader fail] uniform float4 cond; uniform float2x2 a, b; float4 main() : sv_target { return float4(cond ? a : b); } [pixel shader fail] uniform float2x2 cond; uniform float4 a, b; float4 main() : sv_target { return float4(cond ? a : b); } [pixel shader] static float2x2 cond = {1, 0, 0, 1}; static float2x2 a = {1, 2, 3, 4}; static float2x2 b = {5, 6, 7, 8}; float4 main() : sv_target { return float4(cond ? a : b); } [test] draw quad probe (0, 0) rgba (1.0, 6.0, 7.0, 4.0) [pixel shader] static float4 cond = {1, 0, 0, 1}; uniform float4 a; float4 main() : sv_target { return cond ? a : a; } [test] uniform 0 float4 1.0 2.0 3.0 4.0 draw quad probe (0, 0) f32(1.0, 2.0, 3.0, 4.0) [pixel shader] uniform float4 a; float4 main() : sv_target { return float4(false ? a.x : a.y, true ? a.x : a.y, 0, 0); } [test] uniform 0 float4 1.0 2.0 0.0 0.0 draw quad probe (0, 0) f32(2.0, 1.0, 0.0, 0.0) [pixel shader] uniform float c; float4 main() : sv_target { bool cond = c >= 0; return float4(cond ? true : false, cond ? false : true, 0, 0); } [test] uniform 0 float -1.0 draw quad probe (0, 0) f32(0.0, 1.0, 0.0, 0.0) [pixel shader] uniform bool cond; uniform float4 a, b; float4 main() : sv_target { return !cond ? a : b; } [test] if(sm<4) uniform 0 float 0.0 if(sm>=4) uniform 0 uint 0 uniform 4 float4 1.0 2.0 3.0 4.0 uniform 8 float4 5.0 6.0 7.0 8.0 draw quad probe (0, 0) f32(1.0, 2.0, 3.0, 4.0) [pixel shader] uniform float4 a; float4 main() : sv_target { bool cond1 = a.x > 0, cond2 = a.x > 2; float4 ret; ret.x = cond1 ? (cond1 ? a.x : a.y) : a.z; ret.y = cond1 ? a.x : (cond1 ? a.y : a.z); ret.z = cond2 ? (cond2 ? a.x : a.y) : a.z; ret.w = cond2 ? a.x : (cond2 ? a.y : a.z); return ret; } [test] uniform 0 float4 1.0 2.0 3.0 0.0 draw quad probe (0, 0) f32(1.0, 1.0, 3.0, 3.0) [pixel shader] uniform float a; float4 main() : sv_target { bool cond1 = a > 0, cond2 = a > 2; float4 ret; ret.xy = cond1 ? (cond1 ? float2(0, 1) : float2(1, 0)) : float2(1, 1); ret.zw = cond2 ? float2(0, 2) : (cond2 ? float2(2, 0) : float2(2, 2)); return ret; } [test] uniform 0 float 1.0 draw quad probe (0, 0) f32(0.0, 1.0, 2.0, 2.0) [pixel shader] uniform float4 a; float4 main() : sv_target { bool cond1 = a.x > 2, cond2 = a.x > 0, cond3 = a.y > 3; float b = cond1 ? a.x : a.y; float c = cond2 ? a.z : b; float d = cond3 ? a.w : c + 10; float e = cond1 ? a.x : d; return e; } [test] uniform 0 float4 1.0 2.0 3.0 4.0 draw quad probe (0, 0) f32(13.0, 13.0, 13.0, 13.0) [pixel shader fail] uniform float3 cond; uniform float4 a, b; float4 main() : sv_target { (cond ? a : b); return 0; } [pixel shader fail] uniform float4 cond; uniform float4x1 a, b; float4 main() : sv_target { (cond ? a : b); return 0; } % As may be expected, this yields the type of the arguments, not the conditional. [pixel shader] static float4 cond = {1, 0, 0, 1}; static float1x4 a = {1, 2, 3, 4}; static float1x4 b = {5, 6, 7, 8}; float4 main() : sv_target { return (cond ? a : b)[0]; } [test] draw quad probe (0, 0) rgba (1.0, 6.0, 7.0, 4.0) [pixel shader] static float1x4 cond = {1, 0, 0, 1}; static float4 a = {1, 2, 3, 4}; static float4 b = {5, 6, 7, 8}; float4 main() : sv_target { return (cond ? a : b)[0]; } [test] draw quad probe (0, 0) rgba (1.0, 1.0, 1.0, 1.0) [pixel shader fail] uniform float1x4 cond; uniform float4 a, b; float4 main() : sv_target { return (cond ? a : b)[0][0]; } [pixel shader] static float1 cond = {0}; static float1x1 a = {2}; static float1x1 b = {3}; float4 main() : sv_target { return (cond ? a : b)[0][0]; } [test] draw quad probe (0, 0) rgba (3.0, 3.0, 3.0, 3.0) [pixel shader] static float1x1 cond = {1}; static float1 a = {2}; static float1 b = {3}; float4 main() : sv_target { return (cond ? a : b)[0]; } [test] draw quad probe (0, 0) rgba (2.0, 2.0, 2.0, 2.0) [pixel shader fail] static float1x1 cond = {1}; static float1 a = {2}; static float1 b = {3}; float4 main() : sv_target { return (cond ? a : b)[0][0]; } [pixel shader] uniform float cond; uniform float4 a, b; float4 main() : sv_target { return float4(cond ? a : b); } [test] uniform 0 float4 1.0 0.0 0.0 0.0 uniform 4 float4 1.0 2.0 3.0 4.0 uniform 8 float4 5.0 6.0 7.0 8.0 draw quad probe (0, 0) rgba (1.0, 2.0, 3.0, 4.0) [pixel shader] // "scalar" can mean any 1-component numeric type. static float1x1 cond = {0}; static float4 a = {1, 2, 3, 4}; static float4 b = {5, 6, 7, 8}; float4 main() : sv_target { return float4(cond ? a : b); } [test] draw quad probe (0, 0) rgba (5.0, 6.0, 7.0, 8.0) [pixel shader] uniform float4 cond; uniform float4 a, b; float4 main() : sv_target { return float4(cond ? a.x : b.x); } [test] uniform 0 float4 1.0 0.0 1.0 0.0 uniform 4 float4 1.0 2.0 3.0 4.0 uniform 8 float4 5.0 6.0 7.0 8.0 draw quad probe (0, 0) rgba (1.0, 5.0, 1.0, 5.0) [pixel shader] // "scalar" can mean any 1-component numeric type. static float4 cond = {1, 0, 0, 1}; static float1x1 a = {2}; static float1x1 b = {3}; float4 main() : sv_target { return float4(cond ? a : b); } [test] draw quad probe (0, 0) rgba (2.0, 3.0, 3.0, 2.0) % Objects can be used, but their types have to be identical. [pixel shader] Texture2D t; float4 main() : sv_target { Texture2D tmp = 0 ? t : t; return 0; } [pixel shader fail todo] Texture2D t; float4 f; float4 main() : sv_target { f ? t : t; return 0; } [pixel shader fail] Texture2D t; Texture3D u; float4 main() : sv_target { 0 ? t : u; return 0; } % Of course objects cannot be used as the condition. [pixel shader fail] Texture2D t; float4 main() : sv_target { t ? 0 : 1; return 0; }