Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- Makefile.am | 2 + tests/hlsl-mul.shader_test | 78 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 tests/hlsl-mul.shader_test
diff --git a/Makefile.am b/Makefile.am index 3b2e7d71..67225f91 100644 --- a/Makefile.am +++ b/Makefile.am @@ -72,6 +72,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 \ @@ -296,6 +297,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..4d5af691 --- /dev/null +++ b/tests/hlsl-mul.shader_test @@ -0,0 +1,78 @@ +[pixel shader] +float4 main(float4 pos : sv_position) : sv_target +{ + float x = 10.0; + float1 v1 = float1(10.0); + float3 v3 = float3(1.0, 2.0, 3.0); + float4 v4 = float4(1.0, 2.0, 3.0, 4.0); + float1x1 m11 = float1x1(10.0); + float1x4 m14 = float1x4(1.0, 2.0, 3.0, 4.0); + float4x1 m41 = float4x1(1.0, 2.0, 3.0, 4.0); + float3x3 m33 = float3x3(1.0, 2.0, 3.0, + 4.0, 5.0, 6.0, + 7.0, 8.0, 9.0); + float4x4 m44 = 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); + + if (pos.x == 0.5) + return mul(m44, v4); + if (pos.x == 1.5) + return mul(v4, m44); + if (pos.x == 2.5) + return mul(m44, v3); + if (pos.x == 3.5) + return mul(v3, m44); + if (pos.x == 4.5) + return float4(mul(m33, v4), 0.0); + if (pos.x == 5.5) + return float4(mul(v4, m33), 0.0); + if (pos.x == 6.5) + return mul(x, m44)[1]; + if (pos.x == 7.5) + return mul(m44, x)[1]; + if (pos.x == 8.5) + return mul(v1, m44); + if (pos.x == 9.5) + return mul(m44, v1); + if (pos.x == 10.5) + return mul(m11, m44); + if (pos.x == 11.5) + return mul(m44, m11); + if (pos.x == 12.5) + return mul(m14, m44); + if (pos.x == 13.5) + return mul(m44, m14)[1]; + if (pos.x == 14.5) + return mul(m41, m44)[1]; + if (pos.x == 15.5) + return mul(m44, m41); + if (pos.x == 16.5) + return mul(m33, m44)[1]; + if (pos.x == 17.5) + return float4(mul(m44, m33)[1], 0.0); + + return float4(0.0, 0.0, 0.0, 0.0); +} + +[test] +draw quad +probe rgba (0, 0) (30.0, 70.0, 110.0, 150.0) +probe rgba (1, 0) (90.0, 100.0, 110.0, 120.0) +probe rgba (2, 0) (14.0, 38.0, 62.0, 86.0) +probe rgba (3, 0) (38.0, 44.0, 50.0, 56.0) +probe rgba (4, 0) (14.0, 32.0, 50.0, 0.0) +probe rgba (5, 0) (30.0, 36.0, 42.0, 0.0) +probe rgba (6, 0) (50.0, 60.0, 70.0, 80.0) +probe rgba (7, 0) (50.0, 60.0, 70.0, 80.0) +probe rgba (8, 0) (10.0, 20.0, 30.0, 40.0) +probe rgba (9, 0) (10.0, 50.0, 90.0, 130.0) +probe rgba (10, 0) (10.0, 20.0, 30.0, 40.0) +probe rgba (11, 0) (10.0, 50.0, 90.0, 130.0) +probe rgba (12, 0) (90.0, 100.0, 110.0, 120.0) +probe rgba (13, 0) (5.0, 10.0, 15.0, 20.0) +probe rgba (14, 0) (2.0, 4.0, 6.0, 8.0) +probe rgba (15, 0) (30.0, 70.0, 110.0, 150.0) +probe rgba (16, 0) (83.0, 98.0, 113.0, 128.0) +probe rgba (17, 0) (78.0, 96.0, 114.0, 0.0)
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- Makefile.am | 2 + tests/hlsl-operations.shader_test | 86 +++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 tests/hlsl-operations.shader_test
diff --git a/Makefile.am b/Makefile.am index 67225f91..2f36f3a1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -75,6 +75,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 \ @@ -300,6 +301,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..3c8036b5 --- /dev/null +++ b/tests/hlsl-operations.shader_test @@ -0,0 +1,86 @@ +[pixel shader] +float4 main(uniform float zero, uniform float one, uniform float x, uniform float y, + float4 pos : SV_POSITION) : SV_TARGET +{ + int izero = zero; + int ione = one; + int ix = x; + int iy = y; + uint uzero = zero; + uint uone = one; + uint ux = x; + uint uy = y; + + if (pos.x == 0.5) + return float4(x + y, x - y, x * y, x / y); + if (pos.x == 1.5) + return float4(ix + iy, ix - iy, ix * iy, ix / iy); + if (pos.x == 2.5) + return float4(ux + uy, ux - uy, ux * uy, ux / uy); + if (pos.x == 3.5) + return float4(x % y, +x, -x, y / x); + if (pos.x == 4.5) + return float4(ix % iy, +ix, -ix, iy / ix); + if (pos.x == 5.5) + return float4(ux % uy, +ux, -ux, uy / ux); + if (pos.x == 6.5) + return float4(x == y, x != y, x < y, x <= y); + if (pos.x == 7.5) + return float4(x > y, x >= y, !x, !zero); + if (pos.x == 8.5) + return float4(ix == iy, ix != iy, ix < iy, ix <= iy); + if (pos.x == 9.5) + return float4(ix > iy, ix >= iy, !ix, !izero); + if (pos.x == 10.5) + return float4(ix & iy, ix | iy, ix ^ iy, ~ix); + if (pos.x == 11.5) + return float4(ix >> 2, ix << 2, iy >> 2, iy << 2); + if (pos.x == 12.5) + return float4(ux == uy, ux != uy, ux < uy, ux <= uy); + if (pos.x == 13.5) + return float4(ux > uy, ux >= uy, !ux, !uzero); + if (pos.x == 14.5) + return float4(ux & uy, ux | uy, ux ^ uy, ~ux); + if (pos.x == 15.5) + return float4(ux >> 2, ux << 2, uy >> 2, uy << 2); + if (pos.x == 16.5) + return float4(zero && zero, zero && one, one && zero, one && one); + if (pos.x == 17.5) + return float4(zero || zero, zero || one, one || zero, one || one); + if (pos.x == 18.5) + return float4(izero && izero, izero && ione, ione && izero, ione && ione); + if (pos.x == 19.5) + return float4(izero || izero, izero || ione, ione || izero, ione || ione); + if (pos.x == 20.5) + return float4(uzero && uzero, uzero && uone, uone && uzero, uone && uone); + if (pos.x == 21.5) + return float4(uzero || uzero, uzero || uone, uone || uzero, uone || uone); + + return float4(0.0, 0.0, 0.0, 0.0); +} + +[test] +uniform 0 float4 0.0 1.0 5.0 15.0 +draw quad +probe rgba (0, 0) (20.0, -10.0, 75.0, 0.33333333) 1 +probe rgba (1, 0) (20.0, -10.0, 75.0, 0.0) +probe rgba (2, 0) (20.0, 4294967300.0, 75.0, 0.0) +probe rgba (3, 0) (5.0, 5.0, -5.0, 3.0) 1 +probe rgba (4, 0) (5.0, 5.0, -5.0, 3.0) +probe rgba (5, 0) (5.0, 5.0, 4294967300.0, 3.0) +probe rgba (6, 0) (0.0, 1.0, 1.0, 1.0) +probe rgba (7, 0) (0.0, 0.0, 0.0, 1.0) +probe rgba (8, 0) (0.0, 1.0, 1.0, 1.0) +probe rgba (9, 0) (0.0, 0.0, 0.0, 1.0) +probe rgba (10, 0) (5.0, 15.0, 10.0, -6.0) +probe rgba (11, 0) (1.0, 20.0, 3.0, 60.0) +probe rgba (12, 0) (0.0, 1.0, 1.0, 1.0) +probe rgba (13, 0) (0.0, 0.0, 0.0, 1.0) +probe rgba (14, 0) (5.0, 15.0, 10.0, 4294967300.0) +probe rgba (15, 0) (1.0, 20.0, 3.0, 60.0) +probe rgba (16, 0) (0.0, 0.0, 0.0, 1.0) +probe rgba (17, 0) (0.0, 1.0, 1.0, 1.0) +probe rgba (18, 0) (0.0, 0.0, 0.0, 1.0) +probe rgba (19, 0) (0.0, 1.0, 1.0, 1.0) +probe rgba (20, 0) (0.0, 0.0, 0.0, 1.0) +probe rgba (21, 0) (0.0, 1.0, 1.0, 1.0)
On 1/25/22 05:07, Giovanni Mascellani wrote:
diff --git a/tests/hlsl-operations.shader_test b/tests/hlsl-operations.shader_test new file mode 100644 index 00000000..3c8036b5 --- /dev/null +++ b/tests/hlsl-operations.shader_test @@ -0,0 +1,86 @@ +[pixel shader] +float4 main(uniform float zero, uniform float one, uniform float x, uniform float y,
float4 pos : SV_POSITION) : SV_TARGET
+{
- int izero = zero;
- int ione = one;
- int ix = x;
- int iy = y;
- uint uzero = zero;
- uint uone = one;
- uint ux = x;
- uint uy = y;
- if (pos.x == 0.5)
return float4(x + y, x - y, x * y, x / y);
- if (pos.x == 1.5)
return float4(ix + iy, ix - iy, ix * iy, ix / iy);
- if (pos.x == 2.5)
return float4(ux + uy, ux - uy, ux * uy, ux / uy);
- if (pos.x == 3.5)
return float4(x % y, +x, -x, y / x);
- if (pos.x == 4.5)
return float4(ix % iy, +ix, -ix, iy / ix);
- if (pos.x == 5.5)
return float4(ux % uy, +ux, -ux, uy / ux);
- if (pos.x == 6.5)
return float4(x == y, x != y, x < y, x <= y);
- if (pos.x == 7.5)
return float4(x > y, x >= y, !x, !zero);
- if (pos.x == 8.5)
return float4(ix == iy, ix != iy, ix < iy, ix <= iy);
- if (pos.x == 9.5)
return float4(ix > iy, ix >= iy, !ix, !izero);
- if (pos.x == 10.5)
return float4(ix & iy, ix | iy, ix ^ iy, ~ix);
- if (pos.x == 11.5)
return float4(ix >> 2, ix << 2, iy >> 2, iy << 2);
- if (pos.x == 12.5)
return float4(ux == uy, ux != uy, ux < uy, ux <= uy);
- if (pos.x == 13.5)
return float4(ux > uy, ux >= uy, !ux, !uzero);
- if (pos.x == 14.5)
return float4(ux & uy, ux | uy, ux ^ uy, ~ux);
- if (pos.x == 15.5)
return float4(ux >> 2, ux << 2, uy >> 2, uy << 2);
- if (pos.x == 16.5)
return float4(zero && zero, zero && one, one && zero, one && one);
- if (pos.x == 17.5)
return float4(zero || zero, zero || one, one || zero, one || one);
- if (pos.x == 18.5)
return float4(izero && izero, izero && ione, ione && izero, ione && ione);
- if (pos.x == 19.5)
return float4(izero || izero, izero || ione, ione || izero, ione || ione);
- if (pos.x == 20.5)
return float4(uzero && uzero, uzero && uone, uone && uzero, uone && uone);
- if (pos.x == 21.5)
return float4(uzero || uzero, uzero || uone, uone || uzero, uone || uone);
- return float4(0.0, 0.0, 0.0, 0.0);
+}
I don't really like this approach. For one thing, it makes it harder to validate e.g. patches 4-6 from this series (I essentially have to write my own shaders).
The complexity of the generated shader also makes it harder to read the IR to validate it's doing the right thing.
Perhaps more importantly, some of these operations are supported by all HLSL versions, but some are only supported by SM4 (notably integer operations). Anything that can be tested in sm2 or sm3 should be, and as such I'd appreciate splitting those out where possible.
Hi,
Il 25/01/22 19:59, Zebediah Figura (she/her) ha scritto:
I don't really like this approach. For one thing, it makes it harder to validate e.g. patches 4-6 from this series (I essentially have to write my own shaders).
The complexity of the generated shader also makes it harder to read the IR to validate it's doing the right thing.
Perhaps more importantly, some of these operations are supported by all HLSL versions, but some are only supported by SM4 (notably integer operations). Anything that can be tested in sm2 or sm3 should be, and as such I'd appreciate splitting those out where possible.
Would it be better if I splitted this into many little shaders in the same .shader_test file, like I already did for hlsl-shape.shader_test?
Also, is there a difference with 1/6 with this respect, since you signed off on that one?
Giovanni.
On 1/25/22 14:17, Giovanni Mascellani wrote:
Hi,
Il 25/01/22 19:59, Zebediah Figura (she/her) ha scritto:
I don't really like this approach. For one thing, it makes it harder to validate e.g. patches 4-6 from this series (I essentially have to write my own shaders).
The complexity of the generated shader also makes it harder to read the IR to validate it's doing the right thing.
Perhaps more importantly, some of these operations are supported by all HLSL versions, but some are only supported by SM4 (notably integer operations). Anything that can be tested in sm2 or sm3 should be, and as such I'd appreciate splitting those out where possible.
Would it be better if I splitted this into many little shaders in the same .shader_test file, like I already did for hlsl-shape.shader_test?
I think that would be an improvement, yes. It doesn't let us remove them from XFAIL as easily, but it deals with the other problems.
Also, is there a difference with 1/6 with this respect, since you signed off on that one?
Some of the problems apply to 1/6 as well, but I didn't find it problematic enough to complain about. But if you want to resend I won't object to that either.
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- libs/vkd3d-shader/hlsl_sm4.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 8fc4e738..00dfded5 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -745,7 +745,7 @@ struct sm4_instruction { struct sm4_register reg; unsigned int writemask; - } dsts[1]; + } dsts[2]; unsigned int dst_count;
struct @@ -1169,6 +1169,31 @@ 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_null(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; + unsigned int writemask; + + memset(&instr, 0, sizeof(instr)); + instr.opcode = opcode; + + 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; + sm4_register_from_node(&instr.dsts[dst_idx].reg, &instr.dsts[dst_idx].writemask, NULL, dst); + instr.dst_count = 2; + + sm4_register_from_node(&instr.srcs[0].reg, &writemask, &instr.srcs[0].swizzle_type, src1); + instr.srcs[0].swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), instr.dsts[1].writemask); + sm4_register_from_node(&instr.srcs[1].reg, &writemask, &instr.srcs[1].swizzle_type, src2); + instr.srcs[1].swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), instr.dsts[1].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) { @@ -1482,6 +1507,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_null(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;
On 1/25/22 05:07, Giovanni Mascellani wrote:
+static void write_sm4_binary_op_with_null(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;
- unsigned int writemask;
- memset(&instr, 0, sizeof(instr));
- instr.opcode = opcode;
- 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;
- sm4_register_from_node(&instr.dsts[dst_idx].reg, &instr.dsts[dst_idx].writemask, NULL, dst);
- instr.dst_count = 2;
- sm4_register_from_node(&instr.srcs[0].reg, &writemask, &instr.srcs[0].swizzle_type, src1);
- instr.srcs[0].swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), instr.dsts[1].writemask);
- sm4_register_from_node(&instr.srcs[1].reg, &writemask, &instr.srcs[1].swizzle_type, src2);
- instr.srcs[1].swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), instr.dsts[1].writemask);
- instr.src_count = 2;
- write_sm4_instruction(buffer, &instr);
+}
I want to find some way to put "2 dsts" in the function name, because as it is I can't tell just from reading.
I'd also suggest specifying both dsts as optional hlsl_ir_node pointers, where NULL translates to SM4_RT_NULL. That would allow you to use this helper even if both dsts are used.
Hi,
Il 25/01/22 20:06, Zebediah Figura (she/her) ha scritto:
I want to find some way to put "2 dsts" in the function name, because as it is I can't tell just from reading.
Might that be "write_sm4_binary_op_with_two_destinations"?
I'd also suggest specifying both dsts as optional hlsl_ir_node pointers, where NULL translates to SM4_RT_NULL. That would allow you to use this helper even if both dsts are used.
Ok, good idea. Even though in later patches I am always using just one result (and given how our IR is structured, I can't see how it can be different), but generalizing anyway doesn't seem to hurt anybody.
Giovanni.
On 1/25/22 14:19, Giovanni Mascellani wrote:
Hi,
Il 25/01/22 20:06, Zebediah Figura (she/her) ha scritto:
I want to find some way to put "2 dsts" in the function name, because as it is I can't tell just from reading.
Might that be "write_sm4_binary_op_with_two_destinations"?
Yes, although that's a bit unfortunately long.
I'd also suggest specifying both dsts as optional hlsl_ir_node pointers, where NULL translates to SM4_RT_NULL. That would allow you to use this helper even if both dsts are used.
Ok, good idea. Even though in later patches I am always using just one result (and given how our IR is structured, I can't see how it can be different), but generalizing anyway doesn't seem to hurt anybody.
We'll probably want to find a way to combine things via peepholes, at least for things like div/mod and sin/cos. That's not exactly easy to do but shouldn't be too hard either. It's also not really a priority, though.
Hi,
Il 25/01/22 20:06, Zebediah Figura (she/her) ha scritto:
I'd also suggest specifying both dsts as optional hlsl_ir_node pointers, where NULL translates to SM4_RT_NULL. That would allow you to use this helper even if both dsts are used.
Actually, a difficulty with this approach is that then, if both destinations are specified, we don't know which one is to be used to map the sources' writemasks. The ways out I see are to add another argument to specify it, to assume that they are identical so either can be used or to keep the current interface with which exactly one destination is non-NULL (it's true that it is more constraining, but my, admittedly probably poor, understanding of Matteo's intentions is that optimizations like the one you say are going to happen at a lower level, so I wouldn't bother for the time being).
Which one do you prefer?
Giovanni.
On 1/26/22 02:31, Giovanni Mascellani wrote:
Hi,
Il 25/01/22 20:06, Zebediah Figura (she/her) ha scritto:
I'd also suggest specifying both dsts as optional hlsl_ir_node pointers, where NULL translates to SM4_RT_NULL. That would allow you to use this helper even if both dsts are used.
Actually, a difficulty with this approach is that then, if both destinations are specified, we don't know which one is to be used to map the sources' writemasks. The ways out I see are to add another argument to specify it, to assume that they are identical so either can be used or to keep the current interface with which exactly one destination is non-NULL (it's true that it is more constraining, but my, admittedly probably poor, understanding of Matteo's intentions is that optimizations like the one you say are going to happen at a lower level, so I wouldn't bother for the time being).
Which one do you prefer?
I guess that optimization would probably have to happen at a lower level, as you say, and probably even after register allocation.
In that case I'm not sure I have a preference for design.
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index cff56a74..873ba29d 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1057,6 +1057,30 @@ 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) + return NULL; + if (arg2->data_type->base_type == HLSL_TYPE_HALF || arg2->data_type->base_type == HLSL_TYPE_FLOAT) + 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) @@ -3448,7 +3472,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:
On 1/25/22 05:07, Giovanni Mascellani wrote:
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
libs/vkd3d-shader/hlsl.y | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index cff56a74..873ba29d 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1057,6 +1057,30 @@ 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)
return NULL;
- if (arg2->data_type->base_type == HLSL_TYPE_HALF || arg2->data_type->base_type == HLSL_TYPE_FLOAT)
return NULL;
Shouldn't this emit some sort of parse error?
- return add_binary_arithmetic_expr(ctx, instrs, op, arg1, arg2, loc);
+}
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 873ba29d..066396f9 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3479,7 +3479,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: 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 066396f9..73e87af6 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3486,7 +3486,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: Zebediah Figura zfigura@codeweavers.com
---
This will need to be changed to be compatible with SM1, probably by using texcoord instead of sv_position, but that can be deferred for later.