Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v2: * Split to many individual tests --- Makefile.am | 2 + tests/hlsl-mul.shader_test | 290 +++++++++++++++++++++++++++++++++++++ 2 files changed, 292 insertions(+) create mode 100644 tests/hlsl-mul.shader_test
diff --git a/Makefile.am b/Makefile.am index 82807a42..95c2aaa7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -71,6 +71,7 @@ vkd3d_shader_tests = \ tests/hlsl-invalid.shader_test \ tests/hlsl-majority-pragma.shader_test \ tests/hlsl-majority-typedef.shader_test \ + tests/hlsl-mul.shader_test \ tests/hlsl-nested-arrays.shader_test \ tests/hlsl-numeric-types.shader_test \ tests/hlsl-return-implicit-conversion.shader_test \ @@ -302,6 +303,7 @@ XFAIL_TESTS = \ tests/hlsl-intrinsic-override.shader_test \ tests/hlsl-majority-pragma.shader_test \ tests/hlsl-majority-typedef.shader_test \ + tests/hlsl-mul.shader_test \ tests/hlsl-nested-arrays.shader_test \ tests/hlsl-numeric-types.shader_test \ tests/hlsl-return-implicit-conversion.shader_test \ diff --git a/tests/hlsl-mul.shader_test b/tests/hlsl-mul.shader_test new file mode 100644 index 00000000..7b453187 --- /dev/null +++ b/tests/hlsl-mul.shader_test @@ -0,0 +1,290 @@ + +[pixel shader] +float4 main(float4 pos : sv_position) : sv_target +{ + float4x4 x = float4x4(1.0, 2.0, 3.0, 4.0, + 5.0, 6.0, 7.0, 8.0, + 9.0, 10.0, 11.0, 12.0, + 13.0, 14.0, 15.0, 16.0); + float4 y = float4(1.0, 2.0, 3.0, 4.0); + + return mul(x, y); +} + +[test] +draw quad +probe all rgba (30.0, 70.0, 110.0, 150.0) + +[pixel shader] +float4 main(float4 pos : sv_position) : sv_target +{ + float4 x = float4(1.0, 2.0, 3.0, 4.0); + float4x4 y = float4x4(1.0, 2.0, 3.0, 4.0, + 5.0, 6.0, 7.0, 8.0, + 9.0, 10.0, 11.0, 12.0, + 13.0, 14.0, 15.0, 16.0); + + return mul(x, y); +} + +[test] +draw quad +probe all rgba (90.0, 100.0, 110.0, 120.0) + +[pixel shader] +float4 main(float4 pos : sv_position) : sv_target +{ + float4x4 x = float4x4(1.0, 2.0, 3.0, 4.0, + 5.0, 6.0, 7.0, 8.0, + 9.0, 10.0, 11.0, 12.0, + 13.0, 14.0, 15.0, 16.0); + float3 y = float3(1.0, 2.0, 3.0); + + return mul(x, y); +} + +[test] +draw quad +probe all rgba (14.0, 38.0, 62.0, 86.0) + +[pixel shader] +float4 main(float4 pos : sv_position) : sv_target +{ + float3 x = float3(1.0, 2.0, 3.0); + float4x4 y = float4x4(1.0, 2.0, 3.0, 4.0, + 5.0, 6.0, 7.0, 8.0, + 9.0, 10.0, 11.0, 12.0, + 13.0, 14.0, 15.0, 16.0); + + return mul(x, y); +} + +[test] +draw quad +probe all rgba (38.0, 44.0, 50.0, 56.0) + +[pixel shader] +float4 main(float4 pos : sv_position) : sv_target +{ + float3x3 x = float3x3(1.0, 2.0, 3.0, + 4.0, 5.0, 6.0, + 7.0, 8.0, 9.0); + float4 y = float4(1.0, 2.0, 3.0, 4.0); + + return float4(mul(x, y), 0.0); +} + +[test] +draw quad +probe all rgba (14.0, 32.0, 50.0, 0.0) + +[pixel shader] +float4 main(float4 pos : sv_position) : sv_target +{ + float4 x = float4(1.0, 2.0, 3.0, 4.0); + float3x3 y = float3x3(1.0, 2.0, 3.0, + 4.0, 5.0, 6.0, + 7.0, 8.0, 9.0); + + return float4(mul(x, y), 0.0); +} + +[test] +draw quad +probe all rgba (30.0, 36.0, 42.0, 0.0) + +[pixel shader] +float4 main(float4 pos : sv_position) : sv_target +{ + float x = 10.0; + float4x4 y = float4x4(1.0, 2.0, 3.0, 4.0, + 5.0, 6.0, 7.0, 8.0, + 9.0, 10.0, 11.0, 12.0, + 13.0, 14.0, 15.0, 16.0); + + return mul(x, y)[1]; +} + +[test] +draw quad +probe all rgba (50.0, 60.0, 70.0, 80.0) + +[pixel shader] +float4 main(float4 pos : sv_position) : sv_target +{ + float4x4 x = float4x4(1.0, 2.0, 3.0, 4.0, + 5.0, 6.0, 7.0, 8.0, + 9.0, 10.0, 11.0, 12.0, + 13.0, 14.0, 15.0, 16.0); + float y = 10.0; + + return mul(x, y)[1]; +} + +[test] +draw quad +probe all rgba (50.0, 60.0, 70.0, 80.0) + +[pixel shader] +float4 main(float4 pos : sv_position) : sv_target +{ + float1 x = float1(10.0); + float4x4 y = float4x4(1.0, 2.0, 3.0, 4.0, + 5.0, 6.0, 7.0, 8.0, + 9.0, 10.0, 11.0, 12.0, + 13.0, 14.0, 15.0, 16.0); + + return mul(x, y); +} + +[test] +draw quad +probe all rgba (10.0, 20.0, 30.0, 40.0) + +[pixel shader] +float4 main(float4 pos : sv_position) : sv_target +{ + float4x4 x = float4x4(1.0, 2.0, 3.0, 4.0, + 5.0, 6.0, 7.0, 8.0, + 9.0, 10.0, 11.0, 12.0, + 13.0, 14.0, 15.0, 16.0); + float1 y = float1(10.0); + + return mul(x, y); +} + +[test] +draw quad +probe all rgba (10.0, 50.0, 90.0, 130.0) + +[pixel shader] +float4 main(float4 pos : sv_position) : sv_target +{ + float1x1 x = float1x1(10.0); + float4x4 y = float4x4(1.0, 2.0, 3.0, 4.0, + 5.0, 6.0, 7.0, 8.0, + 9.0, 10.0, 11.0, 12.0, + 13.0, 14.0, 15.0, 16.0); + + return mul(x, y); +} + +[test] +draw quad +probe all rgba (10.0, 20.0, 30.0, 40.0) + +[pixel shader] +float4 main(float4 pos : sv_position) : sv_target +{ + float4x4 x = float4x4(1.0, 2.0, 3.0, 4.0, + 5.0, 6.0, 7.0, 8.0, + 9.0, 10.0, 11.0, 12.0, + 13.0, 14.0, 15.0, 16.0); + float1x1 y = float1x1(10.0); + + return mul(x, y); +} + +[test] +draw quad +probe all rgba (10.0, 50.0, 90.0, 130.0) + +[pixel shader] +float4 main(float4 pos : sv_position) : sv_target +{ + float1x4 x = float1x4(1.0, 2.0, 3.0, 4.0); + float4x4 y = float4x4(1.0, 2.0, 3.0, 4.0, + 5.0, 6.0, 7.0, 8.0, + 9.0, 10.0, 11.0, 12.0, + 13.0, 14.0, 15.0, 16.0); + + return mul(x, y); +} + +[test] +draw quad +probe all rgba (90.0, 100.0, 110.0, 120.0) + +[pixel shader] +float4 main(float4 pos : sv_position) : sv_target +{ + float4x4 x = float4x4(1.0, 2.0, 3.0, 4.0, + 5.0, 6.0, 7.0, 8.0, + 9.0, 10.0, 11.0, 12.0, + 13.0, 14.0, 15.0, 16.0); + float1x4 y = float1x4(1.0, 2.0, 3.0, 4.0); + + return mul(x, y)[1]; +} + +[test] +draw quad +probe all rgba (5.0, 10.0, 15.0, 20.0) + +[pixel shader] +float4 main(float4 pos : sv_position) : sv_target +{ + float4x1 x = float4x1(1.0, 2.0, 3.0, 4.0); + float4x4 y = float4x4(1.0, 2.0, 3.0, 4.0, + 5.0, 6.0, 7.0, 8.0, + 9.0, 10.0, 11.0, 12.0, + 13.0, 14.0, 15.0, 16.0); + + return mul(x, y)[1]; +} + +[test] +draw quad +probe all rgba (2.0, 4.0, 6.0, 8.0) + +[pixel shader] +float4 main(float4 pos : sv_position) : sv_target +{ + float4x4 x = float4x4(1.0, 2.0, 3.0, 4.0, + 5.0, 6.0, 7.0, 8.0, + 9.0, 10.0, 11.0, 12.0, + 13.0, 14.0, 15.0, 16.0); + float4x1 y = float4x1(1.0, 2.0, 3.0, 4.0); + + return mul(x, y); +} + +[test] +draw quad +probe all rgba (30.0, 70.0, 110.0, 150.0) + +[pixel shader] +float4 main(float4 pos : sv_position) : sv_target +{ + float3x3 x = float3x3(1.0, 2.0, 3.0, + 4.0, 5.0, 6.0, + 7.0, 8.0, 9.0); + float4x4 y = float4x4(1.0, 2.0, 3.0, 4.0, + 5.0, 6.0, 7.0, 8.0, + 9.0, 10.0, 11.0, 12.0, + 13.0, 14.0, 15.0, 16.0); + + return mul(x, y)[1]; +} + +[test] +draw quad +probe all rgba (83.0, 98.0, 113.0, 128.0) + +[pixel shader] +float4 main(float4 pos : sv_position) : sv_target +{ + float4x4 x = float4x4(1.0, 2.0, 3.0, 4.0, + 5.0, 6.0, 7.0, 8.0, + 9.0, 10.0, 11.0, 12.0, + 13.0, 14.0, 15.0, 16.0); + float3x3 y = float3x3(1.0, 2.0, 3.0, + 4.0, 5.0, 6.0, + 7.0, 8.0, 9.0); + + return float4(mul(x, y)[1], 0.0); +} + +[test] +draw quad +probe all rgba (78.0, 96.0, 114.0, 0.0)
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com -- v2: * Split to many individual tests --- Makefile.am | 2 + tests/hlsl-operations.shader_test | 367 ++++++++++++++++++++++++++++++ 2 files changed, 369 insertions(+) create mode 100644 tests/hlsl-operations.shader_test
diff --git a/Makefile.am b/Makefile.am index 95c2aaa7..24f4f66a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -74,6 +74,7 @@ vkd3d_shader_tests = \ tests/hlsl-mul.shader_test \ tests/hlsl-nested-arrays.shader_test \ tests/hlsl-numeric-types.shader_test \ + tests/hlsl-operations.shader_test \ tests/hlsl-return-implicit-conversion.shader_test \ tests/hlsl-return-void.shader_test \ tests/hlsl-shape.shader_test \ @@ -306,6 +307,7 @@ XFAIL_TESTS = \ tests/hlsl-mul.shader_test \ tests/hlsl-nested-arrays.shader_test \ tests/hlsl-numeric-types.shader_test \ + tests/hlsl-operations.shader_test \ tests/hlsl-return-implicit-conversion.shader_test \ tests/hlsl-return-void.shader_test \ tests/hlsl-shape.shader_test \ diff --git a/tests/hlsl-operations.shader_test b/tests/hlsl-operations.shader_test new file mode 100644 index 00000000..717899b5 --- /dev/null +++ b/tests/hlsl-operations.shader_test @@ -0,0 +1,367 @@ + +[pixel shader] +float4 main() : SV_TARGET +{ + float x = 5.0; + float y = 15.0; + + return float4(x + y, x - y, x * y, x / y); +} + +[test] +draw quad +probe all rgba (20.0, -10.0, 75.0, 0.33333333) + +[pixel shader] +float4 main() : SV_TARGET +{ + float x = 5.0; + float y = 15.0; + + return float4(x % y, +x, -x, y / x); +} + +[test] +draw quad +probe all rgba (5.0, 5.0, -5.0, 3.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + float x = 5.0; + float y = 15.0; + + return float4(x == y, x != y, x < y, x <= y); +} + +[test] +draw quad +probe all rgba (0.0, 1.0, 1.0, 1.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + float x = 5.0; + float y = 15.0; + float zero = 0.0; + + return float4(x > y, x >= y, !x, !zero); +} + +[test] +draw quad +probe all rgba (0.0, 0.0, 0.0, 1.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + float zero = 0.0; + float one = 1.0; + + return float4(zero && zero, zero && one, one && zero, one && one); +} + +[test] +draw quad +probe all rgba (0.0, 0.0, 0.0, 1.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + float zero = 0.0; + float one = 1.0; + + return float4(zero || zero, zero || one, one || zero, one || one); +} + +[test] +draw quad +probe all rgba (0.0, 1.0, 1.0, 1.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + int x = 5; + int y = 15; + + return float4(x + y, x - y, x * y, x / y); +} + +[test] +draw quad +probe all rgba (20.0, -10.0, 75.0, 0.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + int x = 5; + int y = 15; + + return float4(x % y, +x, -x, y / x); +} + +[test] +draw quad +probe all rgba (5.0, 5.0, -5.0, 3.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + int x = 5; + int y = 15; + + return float4(x == y, x != y, x < y, x <= y); +} + +[test] +draw quad +probe all rgba (0.0, 1.0, 1.0, 1.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + int x = 5; + int y = 15; + int zero = 0; + + return float4(x > y, x >= y, !x, !zero); +} + +[test] +draw quad +probe all rgba (0.0, 0.0, 0.0, 1.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + int x = 5; + int y = 15; + + return float4(x >> y, y >> x, x << y, y << x); +} + +[test] +draw quad +probe all rgba (0.0, 0.0, 163840.0, 480.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + int x = 5; + int y = 15; + + return float4(x & y, x | y, x ^ y, ~x); +} + +[test] +draw quad +probe all rgba (5.0, 15.0, 10.0, -6.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + int zero = 0; + int one = 1; + + return float4(zero && zero, zero && one, one && zero, one && one); +} + +[test] +draw quad +probe all rgba (0.0, 0.0, 0.0, 1.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + int zero = 0; + int one = 1; + + return float4(zero || zero, zero || one, one || zero, one || one); +} + +[test] +draw quad +probe all rgba (0.0, 1.0, 1.0, 1.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + int zero = 0; + int one = 1; + + return float4(zero & zero, zero & one, one & zero, one & one); +} + +[test] +draw quad +probe all rgba (0.0, 0.0, 0.0, 1.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + int zero = 0; + int one = 1; + + return float4(zero | zero, zero | one, one | zero, one | one); +} + +[test] +draw quad +probe all rgba (0.0, 1.0, 1.0, 1.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + int zero = 0; + int one = 1; + + return float4(zero ^ zero, zero ^ one, one ^ zero, one ^ one); +} + +[test] +draw quad +probe all rgba (0.0, 1.0, 1.0, 0.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + uint x = 5; + uint y = 15; + + return float4(x + y, x - y, x * y, x / y); +} + +[test] +draw quad +probe all rgba (20.0, 4294967300.0, 75.0, 0.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + uint x = 5; + uint y = 15; + + return float4(x % y, +x, -x, y / x); +} + +[test] +draw quad +probe all rgba (5.0, 5.0, 4294967300.0, 3.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + uint x = 5; + uint y = 15; + + return float4(x == y, x != y, x < y, x <= y); +} + +[test] +draw quad +probe all rgba (0.0, 1.0, 1.0, 1.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + uint x = 5; + uint y = 15; + uint zero = 0; + + return float4(x > y, x >= y, !x, !zero); +} + +[test] +draw quad +probe all rgba (0.0, 0.0, 0.0, 1.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + uint x = 5; + uint y = 15; + + return float4(x >> y, y >> x, x << y, y << x); +} + +[test] +draw quad +probe all rgba (0.0, 0.0, 163840.0, 480.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + uint x = 5; + uint y = 15; + + return float4(x & y, x | y, x ^ y, ~x); +} + +[test] +draw quad +probe all rgba (5.0, 15.0, 10.0, 4294967300.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + uint zero = 0; + uint one = 1; + + return float4(zero && zero, zero && one, one && zero, one && one); +} + +[test] +draw quad +probe all rgba (0.0, 0.0, 0.0, 1.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + uint zero = 0; + uint one = 1; + + return float4(zero || zero, zero || one, one || zero, one || one); +} + +[test] +draw quad +probe all rgba (0.0, 1.0, 1.0, 1.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + uint zero = 0; + uint one = 1; + + return float4(zero & zero, zero & one, one & zero, one & one); +} + +[test] +draw quad +probe all rgba (0.0, 0.0, 0.0, 1.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + uint zero = 0; + uint one = 1; + + return float4(zero | zero, zero | one, one | zero, one | one); +} + +[test] +draw quad +probe all rgba (0.0, 1.0, 1.0, 1.0) + +[pixel shader] +float4 main() : SV_TARGET +{ + uint zero = 0; + uint one = 1; + + return float4(zero ^ zero, zero ^ one, one ^ zero, one ^ one); +} + +[test] +draw quad +probe all rgba (0.0, 1.0, 1.0, 0.0)
Hi, I found something that I am not sure if it may be a problem:
January 28, 2022 5:03 AM, "Giovanni Mascellani" gmascellani@codeweavers.com wrote:
+[test] +draw quad +probe all rgba (20.0, 4294967300.0, 75.0, 0.0)
+[pixel shader] +float4 main() : SV_TARGET +{
- uint x = 5;
- uint y = 15;
- return float4(x % y, +x, -x, y / x);
+}
+[test] +draw quad +probe all rgba (5.0, 5.0, 4294967300.0, 3.0)
The native compiler output is --- ps_4_0 dcl_output o0.xyzw mov o0.xyzw, l(20.000000,4294967296.000000,75.000000,0) ret ---
Probably because float doesn't have enough precision to represent 4294967300.
+[pixel shader] +float4 main() : SV_TARGET +{
- uint x = 5;
- uint y = 15;
- return float4(x == y, x != y, x < y, x <= y);
+}
Same for the next test:
+[test] +draw quad +probe all rgba (0.0, 1.0, 1.0, 1.0)
+[pixel shader] +float4 main() : SV_TARGET +{
- uint x = 5;
- uint y = 15;
- uint zero = 0;
- return float4(x > y, x >= y, !x, !zero);
+}
And this one:
+[pixel shader] +float4 main() : SV_TARGET +{
- uint x = 5;
- uint y = 15;
- return float4(x & y, x | y, x ^ y, ~x);
+}
+[test] +draw quad +probe all rgba (5.0, 15.0, 10.0, 4294967300.0)
Everything else seems okay.
Hi,
Il 28/01/22 15:53, Francisco Casas ha scritto:
Probably because float doesn't have enough precision to represent 4294967300.
Precisely. Technically the native compiler is a bit more correct than what I wrote, because it's true that the actually representable value is 4294967296, not 4294967300. But they both map to the same float value.
A useful tool to experiment with this stuff is https://evanw.github.io/float-toy/.
Giovanni.
Signed-off-by: Francisco Casas fcasas@codeweavers.com
I see! Thanks!
Francisco.
(I resend this email because realized I didn't send the sign-off to wine-devel.)
January 28, 2022 12:36 PM, "Giovanni Mascellani" gmascellani@codeweavers.com wrote:
Hi,
Il 28/01/22 15:53, Francisco Casas ha scritto:
Probably because float doesn't have enough precision to represent 4294967300.
Precisely. Technically the native compiler is a bit more correct than what I wrote, because it's true that the actually representable value is 4294967296, not 4294967300. But they both map to the same float value.
A useful tool to experiment with this stuff is https://evanw.github.io/float-toy.
Giovanni.
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- v2: * Rename to write_sm4_binary_op_with_two_destinations(). * Fix writemask mapping (before it always used the writemask from destination 1, but of course it has to use dst_idx). v3: * Rebased onto master. v4: * Really rebase onto master. I mean, use calls that are available in master. --- libs/vkd3d-shader/hlsl_sm4.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 4eebd583..58d7aef7 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -786,7 +786,7 @@ struct sm4_instruction { struct sm4_register reg; unsigned int writemask; - } dsts[1]; + } dsts[2]; unsigned int dst_count;
struct sm4_src_register @@ -1266,6 +1266,28 @@ static void write_sm4_binary_op(struct vkd3d_bytecode_buffer *buffer, enum vkd3d write_sm4_instruction(buffer, &instr); }
+static void write_sm4_binary_op_with_two_destinations(struct vkd3d_bytecode_buffer *buffer, + enum vkd3d_sm4_opcode opcode, const struct hlsl_ir_node *dst, unsigned dst_idx, + const struct hlsl_ir_node *src1, const struct hlsl_ir_node *src2) +{ + struct sm4_instruction instr; + + memset(&instr, 0, sizeof(instr)); + instr.opcode = opcode; + + sm4_dst_from_node(&instr.dsts[dst_idx], dst); + instr.dsts[1 - dst_idx].reg.type = VKD3D_SM4_RT_NULL; + instr.dsts[1 - dst_idx].reg.dim = VKD3D_SM4_DIMENSION_NONE; + instr.dsts[1 - dst_idx].reg.idx_count = 0; + instr.dst_count = 2; + + sm4_src_from_node(&instr.srcs[0], src1, instr.dsts[dst_idx].writemask); + sm4_src_from_node(&instr.srcs[1], src2, instr.dsts[dst_idx].writemask); + instr.src_count = 2; + + write_sm4_instruction(buffer, &instr); +} + static void write_sm4_constant(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_constant *constant) { @@ -1578,6 +1600,13 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, write_sm4_binary_op(buffer, VKD3D_SM4_OP_UMIN, &expr->node, arg1, arg2); break;
+ case HLSL_OP2_MUL: + /* Using IMUL instead of UMUL because we're taking + * the low bits, and the native compiler generates + * IMUL. */ + write_sm4_binary_op_with_two_destinations(buffer, VKD3D_SM4_OP_IMUL, &expr->node, 1, arg1, arg2); + break; + default: hlsl_fixme(ctx, &expr->node.loc, "SM4 uint "%s" expression.\n", debug_hlsl_expr_op(expr->op)); break;
Signed-off-by: Francisco Casas fcasas@codeweavers.com
January 28, 2022 5:03 AM, "Giovanni Mascellani" gmascellani@codeweavers.com wrote:
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
v2:
- Rename to write_sm4_binary_op_with_two_destinations().
- Fix writemask mapping (before it always used the writemask from
destination 1, but of course it has to use dst_idx). v3:
- Rebased onto master.
v4:
- Really rebase onto master. I mean, use calls that are available in
master.
libs/vkd3d-shader/hlsl_sm4.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 4eebd583..58d7aef7 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -786,7 +786,7 @@ struct sm4_instruction { struct sm4_register reg; unsigned int writemask;
- } dsts[1];
- } dsts[2];
unsigned int dst_count;
struct sm4_src_register @@ -1266,6 +1266,28 @@ static void write_sm4_binary_op(struct vkd3d_bytecode_buffer *buffer, enum vkd3d write_sm4_instruction(buffer, &instr); }
+static void write_sm4_binary_op_with_two_destinations(struct vkd3d_bytecode_buffer *buffer,
- enum vkd3d_sm4_opcode opcode, const struct hlsl_ir_node *dst, unsigned dst_idx,
- const struct hlsl_ir_node *src1, const struct hlsl_ir_node *src2)
+{
- struct sm4_instruction instr;
- memset(&instr, 0, sizeof(instr));
- instr.opcode = opcode;
- sm4_dst_from_node(&instr.dsts[dst_idx], dst);
- instr.dsts[1 - dst_idx].reg.type = VKD3D_SM4_RT_NULL;
- instr.dsts[1 - dst_idx].reg.dim = VKD3D_SM4_DIMENSION_NONE;
- instr.dsts[1 - dst_idx].reg.idx_count = 0;
- instr.dst_count = 2;
- sm4_src_from_node(&instr.srcs[0], src1, instr.dsts[dst_idx].writemask);
- sm4_src_from_node(&instr.srcs[1], src2, instr.dsts[dst_idx].writemask);
- instr.src_count = 2;
- write_sm4_instruction(buffer, &instr);
+}
static void write_sm4_constant(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_constant *constant) { @@ -1578,6 +1600,13 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, write_sm4_binary_op(buffer, VKD3D_SM4_OP_UMIN, &expr->node, arg1, arg2); break;
- case HLSL_OP2_MUL:
- /* Using IMUL instead of UMUL because we're taking
- the low bits, and the native compiler generates
- IMUL. */
- write_sm4_binary_op_with_two_destinations(buffer, VKD3D_SM4_OP_IMUL, &expr->node, 1, arg1, arg2);
- break;
default: hlsl_fixme(ctx, &expr->node.loc, "SM4 uint "%s" expression.\n", debug_hlsl_expr_op(expr->op)); break; -- 2.34.1
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- v2: * Emit error messages. --- libs/vkd3d-shader/hlsl.y | 45 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 9476765f..13268617 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1057,6 +1057,49 @@ static struct list *add_binary_arithmetic_expr_merge(struct hlsl_ctx *ctx, struc return list1; }
+static struct hlsl_ir_expr *add_binary_bitwise_expr(struct hlsl_ctx *ctx, struct list *instrs, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, + const struct vkd3d_shader_location *loc) +{ + if (arg1->data_type->base_type == HLSL_TYPE_HALF || arg1->data_type->base_type == HLSL_TYPE_FLOAT) + { + struct vkd3d_string_buffer *type_str = hlsl_type_to_string(ctx, arg1->data_type); + + if (type_str) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "The first argument has type '%s', which is not integer.", + type_str->buffer); + hlsl_release_string_buffer(ctx, type_str); + return NULL; + } + + if (arg2->data_type->base_type == HLSL_TYPE_HALF || arg2->data_type->base_type == HLSL_TYPE_FLOAT) + { + struct vkd3d_string_buffer *type_str = hlsl_type_to_string(ctx, arg2->data_type); + + if (type_str) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "The second argument has type '%s', which is not integer.", + type_str->buffer); + hlsl_release_string_buffer(ctx, type_str); + return NULL; + } + + return add_binary_arithmetic_expr(ctx, instrs, op, arg1, arg2, loc); +} + +static struct list *add_binary_bitwise_expr_merge(struct hlsl_ctx *ctx, struct list *list1, struct list *list2, + enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg1 = node_from_list(list1), *arg2 = node_from_list(list2); + + list_move_tail(list1, list2); + vkd3d_free(list2); + add_binary_bitwise_expr(ctx, list1, op, arg1, arg2, loc); + + return list1; +} + static struct hlsl_ir_expr *add_binary_comparison_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, struct vkd3d_shader_location *loc) @@ -3554,7 +3597,7 @@ bitand_expr: equality_expr | bitand_expr '&' equality_expr { - hlsl_fixme(ctx, &@$, "Bitwise AND."); + $$ = add_binary_bitwise_expr_merge(ctx, $1, $3, HLSL_OP2_BIT_AND, &@2); }
bitxor_expr:
Signed-off-by: Francisco Casas fcasas@codeweavers.com
Seems good to me, just one detail:
January 28, 2022 5:03 AM, "Giovanni Mascellani" gmascellani@codeweavers.com wrote:
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
v2:
- Emit error messages.
libs/vkd3d-shader/hlsl.y | 45 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 9476765f..13268617 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1057,6 +1057,49 @@ static struct list *add_binary_arithmetic_expr_merge(struct hlsl_ctx *ctx, struc return list1; }
+static struct hlsl_ir_expr *add_binary_bitwise_expr(struct hlsl_ctx *ctx, struct list *instrs,
- enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2,
- const struct vkd3d_shader_location *loc)
+{
- if (arg1->data_type->base_type == HLSL_TYPE_HALF || arg1->data_type->base_type ==
HLSL_TYPE_FLOAT)
- {
For now doubles aren't parsed but this maybe should also throw error on HLSL_TYPE_DOUBLE to be future proof. In that case it may be better to write the contrapositive:
--- if (arg1->data_type->base_type != HLSL_TYPE_INT && arg1->data_type->base_type != HLSL_TYPE_UINT && arg1->data_type->base_type != HLSL_TYPE_BOOL) ---
- struct vkd3d_string_buffer *type_str = hlsl_type_to_string(ctx, arg1->data_type);
- if (type_str)
- hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
- "The first argument has type '%s', which is not integer.",
- type_str->buffer);
- hlsl_release_string_buffer(ctx, type_str);
- return NULL;
- }
- if (arg2->data_type->base_type == HLSL_TYPE_HALF || arg2->data_type->base_type ==
HLSL_TYPE_FLOAT)
Same here.
- {
- struct vkd3d_string_buffer *type_str = hlsl_type_to_string(ctx, arg2->data_type);
- if (type_str)
- hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
- "The second argument has type '%s', which is not integer.",
- type_str->buffer);
- hlsl_release_string_buffer(ctx, type_str);
- return NULL;
- }
- return add_binary_arithmetic_expr(ctx, instrs, op, arg1, arg2, loc);
+}
+static struct list *add_binary_bitwise_expr_merge(struct hlsl_ctx *ctx, struct list *list1, struct list *list2,
- enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc)
+{
- struct hlsl_ir_node *arg1 = node_from_list(list1), *arg2 = node_from_list(list2);
- list_move_tail(list1, list2);
- vkd3d_free(list2);
- add_binary_bitwise_expr(ctx, list1, op, arg1, arg2, loc);
- return list1;
+}
static struct hlsl_ir_expr *add_binary_comparison_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, struct vkd3d_shader_location *loc) @@ -3554,7 +3597,7 @@ bitand_expr: equality_expr | bitand_expr '&' equality_expr {
- hlsl_fixme(ctx, &@$, "Bitwise AND.");
- $$ = add_binary_bitwise_expr_merge(ctx, $1, $3, HLSL_OP2_BIT_AND, &@2);
}
bitxor_expr:
2.34.1
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 13268617..ea13f4e7 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3604,7 +3604,7 @@ bitxor_expr: bitand_expr | bitxor_expr '^' bitand_expr { - hlsl_fixme(ctx, &@$, "Bitwise XOR."); + $$ = add_binary_bitwise_expr_merge(ctx, $1, $3, HLSL_OP2_BIT_XOR, &@2); }
bitor_expr:
Signed-off-by: Francisco Casas fcasas@codeweavers.com
January 28, 2022 4:48 AM, "Giovanni Mascellani" gmascellani@codeweavers.com wrote:
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
libs/vkd3d-shader/hlsl.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 13268617..ea13f4e7 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3604,7 +3604,7 @@ bitxor_expr: bitand_expr | bitxor_expr '^' bitand_expr {
- hlsl_fixme(ctx, &@$, "Bitwise XOR.");
- $$ = add_binary_bitwise_expr_merge(ctx, $1, $3, HLSL_OP2_BIT_XOR, &@2);
}
bitor_expr:
2.34.1
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index ea13f4e7..cee682f3 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3611,7 +3611,7 @@ bitor_expr: bitxor_expr | bitor_expr '|' bitxor_expr { - hlsl_fixme(ctx, &@$, "Bitwise OR."); + $$ = add_binary_bitwise_expr_merge(ctx, $1, $3, HLSL_OP2_BIT_OR, &@2); }
logicand_expr:
Signed-off-by: Francisco Casas fcasas@codeweavers.com
January 28, 2022 5:03 AM, "Giovanni Mascellani" gmascellani@codeweavers.com wrote:
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
libs/vkd3d-shader/hlsl.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index ea13f4e7..cee682f3 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3611,7 +3611,7 @@ bitor_expr: bitxor_expr | bitor_expr '|' bitxor_expr {
- hlsl_fixme(ctx, &@$, "Bitwise OR.");
- $$ = add_binary_bitwise_expr_merge(ctx, $1, $3, HLSL_OP2_BIT_OR, &@2);
}
logicand_expr:
2.34.1
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com
Hmm, this proves that float1 and float are different things:
January 28, 2022 5:03 AM, "Giovanni Mascellani" gmascellani@codeweavers.com wrote:
+[pixel shader] +float4 main(float4 pos : sv_position) : sv_target +{
- float1 x = float1(10.0);
- float4x4 y = float4x4(1.0, 2.0, 3.0, 4.0,
- 5.0, 6.0, 7.0, 8.0,
- 9.0, 10.0, 11.0, 12.0,
- 13.0, 14.0, 15.0, 16.0);
- return mul(x, y);
+}
+[test] +draw quad +probe all rgba (10.0, 20.0, 30.0, 40.0)
It seems that mul checks whether it is a scalar-scalar, scalar-vector, scalar-matrix, vector-scalar, vector-vector, vector-matrix, matrix-scalar, matrix-vector, or matrix-matrix multiplication, using the equivalent to our hlsl_type_class.
This difference makes me wonder whether we are wrong assuming float and float1 are the same in other parts of the codebase, for instance:
--- static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { if (instr->type == HLSL_IR_EXPR) { struct hlsl_ir_expr *expr = hlsl_ir_expr(instr); const struct hlsl_type *src_type = expr->operands[0].node->data_type; const struct hlsl_type *dst_type = expr->node.data_type;
if (expr->op != HLSL_OP1_CAST) return false;
if (hlsl_types_are_equal(src_type, dst_type) || (src_type->base_type == dst_type->base_type && is_vec1(src_type) && is_vec1(dst_type))) { replace_node(&expr->node, expr->operands[0].node); return true; } }
return false; } ---
would dismiss a cast from float to float1, and, if I am not mistaken, the compiler would be failing with this shader:
--- float4 main(float4 pos : sv_position) : sv_target { float xx = 10.0; float1 x = float1(xx); float4x4 y = float4x4(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0);
return mul(x, y); } ---
Hi,
Il 28/01/22 14:35, Francisco Casas ha scritto:
It seems that mul checks whether it is a scalar-scalar, scalar-vector, scalar-matrix, vector-scalar, vector-vector, vector-matrix, matrix-scalar, matrix-vector, or matrix-matrix multiplication, using the equivalent to our hlsl_type_class.
This difference makes me wonder whether we are wrong assuming float and float1 are the same in other parts of the codebase, for instance:
As you say float and float1 are two different things in HLSL, but once we are deep enough in the pipeline that all the relevant operations (like mul()) have been lowered, then we can ignore the difference. As (I think) I have said in another email, what I would like to happen is that at some point everything is converted to vectors (so we don't have scalars lingering around anymore), but it doesn't seem that the others agree with me.
Giovanni.
On 1/28/22 09:33, Giovanni Mascellani wrote:
Hi,
Il 28/01/22 14:35, Francisco Casas ha scritto:
It seems that mul checks whether it is a scalar-scalar, scalar-vector, scalar-matrix, vector-scalar, vector-vector, vector-matrix, matrix-scalar, matrix-vector, or matrix-matrix multiplication, using the equivalent to our hlsl_type_class.
This difference makes me wonder whether we are wrong assuming float and float1 are the same in other parts of the codebase, for instance:
As you say float and float1 are two different things in HLSL, but once we are deep enough in the pipeline that all the relevant operations (like mul()) have been lowered, then we can ignore the difference.
Basically this, yes. I think we should preserve HLSL type information for the duration of yyparse(), so that we can do type checking, but as soon as we get out we shouldn't be caring at all.
As (I think) I have said in another email, what I would like to happen is that at some point everything is converted to vectors (so we don't have scalars lingering around anymore), but it doesn't seem that the others agree with me.
I personally just don't see it as necessary. In particular there's not really much difference between
type->class == HLSL_CLASS_VECTOR && type->dimx == 1
and
type->class <= HLSL_CLASS_VECTOR && type->dimx == 1