[PATCH 0/2] MR740: Implement hyperbolic trigonometry operations.
I'm working on adding all the intrinsics we haven't implemented yet. Here's sinh, cosh, and tanh. Sinh/cosh are implemented in the same commit because they forward to the same backing function (because the identities used only differ by a plus or minus). -- https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/740
From: Petrichor Park <ppark(a)codeweavers.com> Also tightens the TODOs on some of the tests. --- libs/vkd3d-shader/hlsl.y | 55 +++++++++++++++++++++++++++++ tests/hlsl/trigonometry.shader_test | 16 ++++----- 2 files changed, 63 insertions(+), 8 deletions(-) diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index ec8b3d22a..e4a5bf1f3 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3022,6 +3022,53 @@ static bool intrinsic_cos(struct hlsl_ctx *ctx, return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_COS, arg, loc); } +static bool write_cosh_or_sinh(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc, bool sinh_mode) +{ + struct hlsl_ir_function_decl *func; + struct hlsl_type *type; + const char *fn_name, *combiner; + char *body; + + static const char template[] = + "%s %s(%s x)\n" + "{\n" + " %s expPos, expNeg, combined;" + " expPos = exp(x);\n" + " expNeg = exp(-x);\n" + " combined = %s;\n" + " return combined / 2;\n" + "}\n"; + static const char fn_name_sinh[] = "sinh"; + static const char fn_name_cosh[] = "cosh"; + static const char combiner_sinh[] = "expPos - expNeg"; + static const char combiner_cosh[] = "expPos + expNeg"; + + type = params->args[0]->data_type; + type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->dimx, type->dimy); + + fn_name = sinh_mode ? fn_name_sinh : fn_name_cosh; + combiner = sinh_mode ? combiner_sinh : combiner_cosh; + + if (!(body = hlsl_sprintf_alloc(ctx, template, + type->name, fn_name, type->name, + type->name, combiner))) + return false; + + func = hlsl_compile_internal_function(ctx, fn_name, body); + vkd3d_free(body); + if (!func) + return false; + + return add_user_call(ctx, func, params, loc); +} + +static bool intrinsic_cosh(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + return write_cosh_or_sinh(ctx, params, loc, false); +} + static bool intrinsic_cross(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -3814,6 +3861,12 @@ static bool intrinsic_sin(struct hlsl_ctx *ctx, return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SIN, arg, loc); } +static bool intrinsic_sinh(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + return write_cosh_or_sinh(ctx, params, loc, true); +} + /* smoothstep(a, b, x) = p^2 (3 - 2p), where p = saturate((x - a)/(b - a)) */ static bool intrinsic_smoothstep(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) @@ -4218,6 +4271,7 @@ intrinsic_functions[] = {"clamp", 3, true, intrinsic_clamp}, {"clip", 1, true, intrinsic_clip}, {"cos", 1, true, intrinsic_cos}, + {"cosh", 1, true, intrinsic_cosh}, {"cross", 2, true, intrinsic_cross}, {"ddx", 1, true, intrinsic_ddx}, {"ddx_coarse", 1, true, intrinsic_ddx_coarse}, @@ -4254,6 +4308,7 @@ intrinsic_functions[] = {"saturate", 1, true, intrinsic_saturate}, {"sign", 1, true, intrinsic_sign}, {"sin", 1, true, intrinsic_sin}, + {"sinh", 1, true, intrinsic_sinh}, {"smoothstep", 3, true, intrinsic_smoothstep}, {"sqrt", 1, true, intrinsic_sqrt}, {"step", 2, true, intrinsic_step}, diff --git a/tests/hlsl/trigonometry.shader_test b/tests/hlsl/trigonometry.shader_test index 3f7f11685..392728098 100644 --- a/tests/hlsl/trigonometry.shader_test +++ b/tests/hlsl/trigonometry.shader_test @@ -76,7 +76,7 @@ todo(sm<4 | glsl) draw quad probe all rgba (0, 1000, -1000.0, 0) -[pixel shader todo] +[pixel shader] uniform float4 a; float4 main() : sv_target @@ -86,15 +86,15 @@ float4 main() : sv_target [test] uniform 0 float4 -6.28318531 -0.88137359 0.88137359 6.28318531 -todo(sm<6) draw quad +todo(glsl) draw quad probe all rgba (-267.744894, -1.0, 1.0, 267.744894) 2 uniform 0 float4 -0.0 0.0 -90.0 90.0 -todo(sm<6) draw quad +todo(glsl) draw quad % mingw does not support "inf" for scanf(), but numbers beyond FLOAT_MAX consistently result in inf. probe all rgba (0.0, 0.0, -1.0e39, 1.0e39) 1 -[pixel shader todo] +[pixel shader] uniform float4 a; float4 main() : sv_target @@ -104,10 +104,10 @@ float4 main() : sv_target [test] uniform 0 float4 -1.76274717 -1.3169579 1.3169579 1.76274717 -todo(sm<6) draw quad +todo(glsl) draw quad probe all rgba (3.0, 2.0, 2.0, 3.0) 2 uniform 0 float4 -0.0 0.0 -90.0 90.0 -todo(sm<6) draw quad +todo(glsl) draw quad probe all rgba (1.0, 1.0, 1.0e39, 1.0e39) 1 @@ -121,8 +121,8 @@ float4 main() : sv_target [test] uniform 0 float4 -1.57079633 -0.54930614 0.54930614 1.57079633 -todo(sm<6) draw quad +todo draw quad probe all rgba (-0.91715234, -0.5, 0.5, 0.91715234) 2 uniform 0 float4 -10.0 -0.0 0.0 10.0 -todo(sm<6) draw quad +todo draw quad probe all rgba (-1.0, 0.0, 0.0, 1.0) 1 -- GitLab https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/740
From: Petrichor Park <ppark(a)codeweavers.com> --- libs/vkd3d-shader/hlsl.y | 32 +++++++++++++++++++++++++++++ tests/hlsl/trigonometry.shader_test | 6 +++--- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index e4a5bf1f3..a5ea27ad3 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3939,6 +3939,37 @@ static bool intrinsic_tan(struct hlsl_ctx *ctx, return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_DIV, sin, cos, loc); } +static bool intrinsic_tanh(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_function_decl *func; + struct hlsl_type *type; + char *body; + + static const char template[] = + "%s tanh(%s x)\n" + "{\n" + " %s expPos, expNeg;\n" + " expPos = exp(x);\n" + " expNeg = exp(-x);\n" + " return (expPos - expNeg) / (expPos + expNeg);\n" + "}\n"; + + type = params->args[0]->data_type; + type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->dimx, type->dimy); + + if (!(body = hlsl_sprintf_alloc(ctx, template, + type->name, type->name, type->name))) + return false; + + func = hlsl_compile_internal_function(ctx, "tanh", body); + vkd3d_free(body); + if (!func) + return false; + + return add_user_call(ctx, func, params, loc); +} + static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc, const char *name, enum hlsl_sampler_dim dim) { @@ -4313,6 +4344,7 @@ intrinsic_functions[] = {"sqrt", 1, true, intrinsic_sqrt}, {"step", 2, true, intrinsic_step}, {"tan", 1, true, intrinsic_tan}, + {"tanh", 1, true, intrinsic_tanh}, {"tex1D", -1, false, intrinsic_tex1D}, {"tex2D", -1, false, intrinsic_tex2D}, {"tex2Dlod", 2, false, intrinsic_tex2Dlod}, diff --git a/tests/hlsl/trigonometry.shader_test b/tests/hlsl/trigonometry.shader_test index 392728098..cf6165876 100644 --- a/tests/hlsl/trigonometry.shader_test +++ b/tests/hlsl/trigonometry.shader_test @@ -111,7 +111,7 @@ todo(glsl) draw quad probe all rgba (1.0, 1.0, 1.0e39, 1.0e39) 1 -[pixel shader todo] +[pixel shader] uniform float4 a; float4 main() : sv_target @@ -121,8 +121,8 @@ float4 main() : sv_target [test] uniform 0 float4 -1.57079633 -0.54930614 0.54930614 1.57079633 -todo draw quad +todo(glsl) draw quad probe all rgba (-0.91715234, -0.5, 0.5, 0.91715234) 2 uniform 0 float4 -10.0 -0.0 0.0 10.0 -todo draw quad +todo(glsl) draw quad probe all rgba (-1.0, 0.0, 0.0, 1.0) 1 -- GitLab https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/740
Zebediah Figura (@zfigura) commented about libs/vkd3d-shader/hlsl.y:
+static bool write_cosh_or_sinh(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc, bool sinh_mode) +{ + struct hlsl_ir_function_decl *func; + struct hlsl_type *type; + const char *fn_name, *combiner; + char *body; + + static const char template[] = + "%s %s(%s x)\n" + "{\n" + " %s expPos, expNeg, combined;" + " expPos = exp(x);\n" + " expNeg = exp(-x);\n" + " combined = %s;\n" + " return combined / 2;\n" Let's avoid camel case please. That said, though, the function seems simple enough that I'd just write "return (exp(x) ± exp(-x)) / 2"?
-- https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/740#note_66304
Zebediah Figura (@zfigura) commented about libs/vkd3d-shader/hlsl.y:
+ static const char template[] = + "%s %s(%s x)\n" + "{\n" + " %s expPos, expNeg, combined;" + " expPos = exp(x);\n" + " expNeg = exp(-x);\n" + " combined = %s;\n" + " return combined / 2;\n" + "}\n"; + static const char fn_name_sinh[] = "sinh"; + static const char fn_name_cosh[] = "cosh"; + static const char combiner_sinh[] = "expPos - expNeg"; + static const char combiner_cosh[] = "expPos + expNeg"; + + type = params->args[0]->data_type; + type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->dimx, type->dimy); We probably want intrinsic_float_convert_arg() instead.
-- https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/740#note_66305
Giovanni Mascellani (@giomasce) commented about tests/hlsl/trigonometry.shader_test:
[test] uniform 0 float4 -1.57079633 -0.54930614 0.54930614 1.57079633 -todo(sm<6) draw quad +todo draw quad probe all rgba (-0.91715234, -0.5, 0.5, 0.91715234) 2 uniform 0 float4 -10.0 -0.0 0.0 10.0 -todo(sm<6) draw quad +todo draw quad
These two changes fail (i.e., unexpectedly succeed) on the CI and on every implementation I've got. Is it possible it's a mistake? Which hardware are you testing on? -- https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/740#note_66362
Also tightens the TODOs on some of the tests.
I don't think there is need to specify this, every time you add a feature you tighten the corresponding TODOs. -- https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/740#note_66363
On Thu Mar 28 11:39:57 2024 +0000, Giovanni Mascellani wrote:
These two changes fail (i.e., unexpectedly succeed) on the CI and on every implementation I've got. Is it possible it's a mistake? Which hardware are you testing on? I'm testing on KDE neon 6.0 on a ThinkPad E15 Gen 4. It does pass on my machine, except for the native implementation. Francisco and I were talking about how the local native failures are probably false negatives.
-- https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/740#note_66483
participants (4)
-
Giovanni Mascellani (@giomasce) -
Petrichor Park -
Petrichor Park (@petrathekat) -
Zebediah Figura (@zfigura)