Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
-- v2: vkd3d-shader/hlsl: Add constant folding for binary complement operator. vkd3d-shader/hlsl: Add constant folding for rshift. vkd3d-shader/hlsl: Add constant folding for lshift. vkd3d-shader/hlsl: Add constant folding for logical 'not', for bools.
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl_constant_ops.c | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d-shader/hlsl_constant_ops.c index cff0ba31..3b4c86dc 100644 --- a/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d-shader/hlsl_constant_ops.c @@ -334,6 +334,30 @@ static bool fold_neg(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, return true; }
+static bool fold_not(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, + const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) +{ + enum hlsl_base_type type = dst_type->base_type; + unsigned int k; + + assert(type == src->node.data_type->base_type); + + for (k = 0; k < dst_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_BOOL: + dst->u[k].u = ~src->value.u[k].u; + break; + + default: + FIXME("Fold logic 'not' for type %s.\n", debug_hlsl_type(ctx, dst_type)); + return false; + } + } + return true; +} + static bool fold_rcp(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc) { @@ -1091,6 +1115,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, success = fold_neg(ctx, &res, instr->data_type, arg1); break;
+ case HLSL_OP1_LOGIC_NOT: + success = fold_not(ctx, &res, instr->data_type, arg1); + break; + case HLSL_OP1_RCP: success = fold_rcp(ctx, &res, instr->data_type, arg1, &instr->loc); break;
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl_constant_ops.c | 34 +++++++++++++++++++++++++++ tests/hlsl/bitwise.shader_test | 15 ++++++++++++ 2 files changed, 49 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d-shader/hlsl_constant_ops.c index 3b4c86dc..b681b2d3 100644 --- a/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d-shader/hlsl_constant_ops.c @@ -832,6 +832,36 @@ static bool fold_less(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, con return true; }
+static bool fold_lshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, + const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) +{ + unsigned int k; + + assert(dst_type->base_type == src1->node.data_type->base_type); + assert(src2->node.data_type->base_type == HLSL_TYPE_INT); + + for (k = 0; k < dst_type->dimx; ++k) + { + unsigned int shift = src2->value.u[k].u % 32; + + switch (src1->node.data_type->base_type) + { + case HLSL_TYPE_INT: + dst->u[k].i = src1->value.u[k].i << shift; + break; + + case HLSL_TYPE_UINT: + dst->u[k].u = src1->value.u[k].u << shift; + break; + + default: + vkd3d_unreachable(); + } + } + + return true; +} + static bool fold_max(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) { @@ -1169,6 +1199,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, success = fold_less(ctx, &res, instr->data_type, arg1, arg2); break;
+ case HLSL_OP2_LSHIFT: + success = fold_lshift(ctx, &res, instr->data_type, arg1, arg2); + break; + case HLSL_OP2_MAX: success = fold_max(ctx, &res, instr->data_type, arg1, arg2); break; diff --git a/tests/hlsl/bitwise.shader_test b/tests/hlsl/bitwise.shader_test index 55160037..08f02105 100644 --- a/tests/hlsl/bitwise.shader_test +++ b/tests/hlsl/bitwise.shader_test @@ -14,6 +14,21 @@ float4 main() : SV_TARGET draw quad probe all rgba (0.0, 0.0, 163840.0, 480.0)
+[pixel shader] +float4 main() : sv_target +{ + int x = 1; + int y = -1; + int z = 34; + uint x2 = 1; + + return float4(x << y, x << z, x2 << y, x2 << z); +} + +[test] +draw quad +probe all rgba (-2147483648.0, 4.0, 2147483650.0, 4.0) + [pixel shader] float4 main() : SV_TARGET {
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl_constant_ops.c | 34 +++++++++++++++++++++++++++ tests/hlsl/bitwise.shader_test | 15 ++++++++++++ 2 files changed, 49 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d-shader/hlsl_constant_ops.c index b681b2d3..3e8c3fc1 100644 --- a/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d-shader/hlsl_constant_ops.c @@ -1086,6 +1086,36 @@ static bool fold_ternary(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, return true; }
+static bool fold_rshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, + const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) +{ + unsigned int k; + + assert(dst_type->base_type == src1->node.data_type->base_type); + assert(src2->node.data_type->base_type == HLSL_TYPE_INT); + + for (k = 0; k < dst_type->dimx; ++k) + { + unsigned int shift = src2->value.u[k].u % 32; + + switch (src1->node.data_type->base_type) + { + case HLSL_TYPE_INT: + dst->u[k].i = src1->value.u[k].i >> shift; + break; + + case HLSL_TYPE_UINT: + dst->u[k].u = src1->value.u[k].u >> shift; + break; + + default: + vkd3d_unreachable(); + } + } + + return true; +} + bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct hlsl_ir_constant *arg1, *arg2 = NULL, *arg3 = NULL; @@ -1223,6 +1253,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, success = fold_nequal(ctx, &res, instr->data_type, arg1, arg2); break;
+ case HLSL_OP2_RSHIFT: + success = fold_rshift(ctx, &res, instr->data_type, arg1, arg2); + break; + case HLSL_OP3_DP2ADD: success = fold_dp2add(ctx, &res, instr->data_type, arg1, arg2, arg3); break; diff --git a/tests/hlsl/bitwise.shader_test b/tests/hlsl/bitwise.shader_test index 08f02105..20a9db55 100644 --- a/tests/hlsl/bitwise.shader_test +++ b/tests/hlsl/bitwise.shader_test @@ -29,6 +29,21 @@ float4 main() : sv_target draw quad probe all rgba (-2147483648.0, 4.0, 2147483650.0, 4.0)
+[pixel shader] +float4 main() : sv_target +{ + int x = 2147483647; + int y = -1; + int z = 34; + uint x2 = 4294967295; + + return float4(x >> y, x >> z, x2 >> y, x2 >> z); +} + +[test] +draw quad +probe all rgba (0.0, 536870912.0, 1.0, 1073741824.0) + [pixel shader] float4 main() : SV_TARGET {
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl_constant_ops.c | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d-shader/hlsl_constant_ops.c index 3e8c3fc1..c9554fd5 100644 --- a/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d-shader/hlsl_constant_ops.c @@ -113,6 +113,32 @@ static int32_t double_to_int(double x) return x; }
+static bool fold_bit_not(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, + const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) +{ + enum hlsl_base_type type = dst_type->base_type; + unsigned int k; + + assert(type == src->node.data_type->base_type); + + for (k = 0; k < dst_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + case HLSL_TYPE_BOOL: + dst->u[k].u = ~src->value.u[k].u; + break; + + default: + vkd3d_unreachable(); + } + } + + return true; +} + static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) { @@ -1155,6 +1181,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, success = fold_abs(ctx, &res, instr->data_type, arg1); break;
+ case HLSL_OP1_BIT_NOT: + success = fold_bit_not(ctx, &res, instr->data_type, arg1); + break; + case HLSL_OP1_CAST: success = fold_cast(ctx, &res, instr->data_type, arg1); break;
On Mon Sep 25 13:33:54 2023 +0000, Nikolay Sivov wrote:
changed this line in [version 2 of the diff](/wine/vkd3d/-/merge_requests/363/diffs?diff_id=71619&start_sha=445cf940b3bb136bbb6e1b95f6b34341ae0733d5#42d7bc823e29607ffee11286a3147a03c3ae6ce6_376_376)
Ack.
On Mon Sep 25 13:33:55 2023 +0000, Nikolay Sivov wrote:
changed this line in [version 2 of the diff](/wine/vkd3d/-/merge_requests/363/diffs?diff_id=71619&start_sha=445cf940b3bb136bbb6e1b95f6b34341ae0733d5#42d7bc823e29607ffee11286a3147a03c3ae6ce6_874_876)
From what I can tell it already works as-is, UB or not. Let me know if suggested change is not enough.
On Tue Sep 26 08:12:17 2023 +0000, Nikolay Sivov wrote:
From what I can tell it already works as-is, UB or not. Let me know if suggested change is not enough.
Yeah, now it looks correct. Thanks!
This merge request was approved by Giovanni Mascellani.
This merge request was approved by Zebediah Figura.
This merge request was approved by Henri Verbeet.