From: Zebediah Figura zfigura@codeweavers.com
--- Makefile.am | 1 + tests/hlsl/sm6-ternary.shader_test | 46 +++++ tests/hlsl/ternary.shader_test | 311 +++++++++++++++++++++++++++-- 3 files changed, 344 insertions(+), 14 deletions(-) create mode 100644 tests/hlsl/sm6-ternary.shader_test
diff --git a/Makefile.am b/Makefile.am index 2666194a6..fa5afe7a8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -161,6 +161,7 @@ vkd3d_shader_tests = \ tests/hlsl/side-effects.shader_test \ tests/hlsl/sign.shader_test \ tests/hlsl/single-numeric-initializer.shader_test \ + tests/hlsl/sm6-ternary.shader_test \ tests/hlsl/smoothstep.shader_test \ tests/hlsl/sqrt.shader_test \ tests/hlsl/state-block-syntax.shader_test \ diff --git a/tests/hlsl/sm6-ternary.shader_test b/tests/hlsl/sm6-ternary.shader_test new file mode 100644 index 000000000..349d32676 --- /dev/null +++ b/tests/hlsl/sm6-ternary.shader_test @@ -0,0 +1,46 @@ +% The ternary operator works differently in sm6. +% It now shortcuts, and is no longer per-component. + +[require] +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 +todo draw quad +probe all rgba (2.0, 3.0, 4.0, 5.0) +uniform 0 float4 0.0 10.0 11.0 12.0 +todo draw quad +probe all rgba (-1.0, 9.0, 10.0, 11.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 all rgba (0.5, 0.2, 0.7, 0.0) + + +[pixel shader fail] +float4 x, y, z; + +float4 main() : sv_target +{ + return x ? y : z; +} diff --git a/tests/hlsl/ternary.shader_test b/tests/hlsl/ternary.shader_test index 7b4c71f7b..fbc0b7377 100644 --- a/tests/hlsl/ternary.shader_test +++ b/tests/hlsl/ternary.shader_test @@ -1,3 +1,8 @@ +[require] +% The ternary operator works differently in sm6. See sm6-ternary.shader_test. +shader model < 6.0 + + [pixel shader] uniform float4 x;
@@ -8,12 +13,13 @@ float4 main() : sv_target
[test] uniform 0 float4 2.0 3.0 4.0 5.0 -todo(sm>=6) draw quad +draw quad probe all rgba (2.0, 3.0, 4.0, 5.0) uniform 0 float4 0.0 10.0 11.0 12.0 -todo(sm>=6) draw quad +draw quad probe all rgba (-1.0, 9.0, 10.0, 11.0)
+ [pixel shader] uniform float4 x;
@@ -32,6 +38,7 @@ uniform 0 float4 1.1 3.0 4.0 5.0 draw quad probe all rgba (1.1, 2.0, 0.0, 0.0)
+ [pixel shader] float4 f;
@@ -42,37 +49,313 @@ float4 main() : sv_target return float4(f1, f2, f3, 0.0); }
-[require] -shader model < 6.0
[test] uniform 0 float4 1.0 0.0 0.0 0.0 draw quad probe all rgba (0.5, 0.6, 0.7, 0.0)
-[require] -shader model >= 6.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 all rgba (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 all 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 all rgba (5.0, 6.0, 7.0, 1.0) + + +% The condition is more restrictive. Either: +% * the class and dimensions must match exactly; +% * one of the two is scalar; +% * one is a typeN and the other is a type1xN + +[pixel shader fail todo] + +uniform float4 cond; +uniform float2x2 a, b; + +float4 main() : sv_target +{ + return float4(cond ? a : b); +} + + +[pixel shader fail todo] + +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 all rgba (1.0, 6.0, 7.0, 4.0) + + +[pixel shader fail todo] + +uniform float3 cond; +uniform float4 a, b; + +float4 main() : sv_target +{ + (cond ? a : b); + return 0; +} + + +[pixel shader fail todo] + +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 all rgba (1.0, 6.0, 7.0, 4.0) + + +[pixel shader todo] + +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 all 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 all rgba (3.0, 3.0, 3.0, 3.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 all rgba (0.5, 0.2, 0.7, 0.0) +probe all rgba (1.0, 2.0, 3.0, 4.0)
-[require] -% reset requirements
+[pixel shader todo]
-[pixel shader fail(sm>=6)] -float4 x, y, z; +// "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 x ? y : z; + return float4(cond ? a : b); }
[test] -uniform 0 float4 0.0 1.0 0.0 -3.0 +draw quad +probe all rgba (5.0, 6.0, 7.0, 8.0) + + +[pixel shader todo] + +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 +todo draw quad +probe all rgba (1.0, 5.0, 1.0, 5.0) + + +[pixel shader todo] + +// "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 all rgba (5.0, 2.0, 7.0, 4.0) +probe all rgba (2.0, 3.0, 3.0, 2.0) + + +% Objects can be used, but their types have to be identical. + +[pixel shader todo] +Texture2D t; + +float4 main() : sv_target +{ + Texture2D tmp = 0 ? t : t; + return 0; +} + + +[pixel shader fail] +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 todo] +Texture2D t; + +float4 main() : sv_target +{ + t ? 0 : 1; + return 0; +}