-- v4: vkd3d-shader/hlsl: Add degrees() function.
From: Akihiro Sagawa sagawa.aki@gmail.com
--- Makefile.am | 1 + libs/vkd3d-shader/hlsl.y | 17 +++++++++++++++++ tests/hlsl/angle-unit.shader_test | 12 ++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 tests/hlsl/angle-unit.shader_test
diff --git a/Makefile.am b/Makefile.am index 2666194a6..7d5898193 100644 --- a/Makefile.am +++ b/Makefile.am @@ -46,6 +46,7 @@ vkd3d_cross_tests = \ vkd3d_shader_tests = \ tests/hlsl/abs.shader_test \ tests/hlsl/all.shader_test \ + tests/hlsl/angle-unit.shader_test \ tests/hlsl/any.shader_test \ tests/hlsl/arithmetic-float-uniform.shader_test \ tests/hlsl/arithmetic-float.shader_test \ diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 5e0d48d3c..a9ff41aa8 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3341,6 +3341,22 @@ static bool intrinsic_pow(struct hlsl_ctx *ctx, return !!add_pow_expr(ctx, params->instrs, params->args[0], params->args[1], loc); }
+static bool intrinsic_radians(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg, *rad; + + if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + return false; + + /* 1 degree = pi/180 rad = 0.0174532925f rad */ + if (!(rad = hlsl_new_float_constant(ctx, 0.0174532925f, loc))) + return false; + hlsl_block_add_instr(params->instrs, rad); + + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg, rad, loc); +} + static bool intrinsic_reflect(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -3869,6 +3885,7 @@ intrinsic_functions[] = {"mul", 2, true, intrinsic_mul}, {"normalize", 1, true, intrinsic_normalize}, {"pow", 2, true, intrinsic_pow}, + {"radians", 1, true, intrinsic_radians}, {"reflect", 2, true, intrinsic_reflect}, {"round", 1, true, intrinsic_round}, {"rsqrt", 1, true, intrinsic_rsqrt}, diff --git a/tests/hlsl/angle-unit.shader_test b/tests/hlsl/angle-unit.shader_test new file mode 100644 index 000000000..6e0538f98 --- /dev/null +++ b/tests/hlsl/angle-unit.shader_test @@ -0,0 +1,12 @@ +[pixel shader] +uniform float4 a; + +float4 main() : sv_target +{ + return radians(a); +} + +[test] +uniform 0 float4 0.0 30.0 150.0 180.0 +draw quad +probe all rgba (0.0, 0.52359877, 2.61799387, 3.14159265)
From: Akihiro Sagawa sagawa.aki@gmail.com
--- libs/vkd3d-shader/hlsl.y | 17 +++++++++++++++++ tests/hlsl/angle-unit.shader_test | 14 ++++++++++++++ 2 files changed, 31 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index a9ff41aa8..242e8307d 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2878,6 +2878,22 @@ static bool intrinsic_ddy_coarse(struct hlsl_ctx *ctx, return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_DSY_COARSE, arg, loc); }
+static bool intrinsic_degrees(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg, *deg; + + if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + return false; + + /* 1 rad = 180/pi degree = 57.2957795 degree */ + if (!(deg = hlsl_new_float_constant(ctx, 57.2957795f, loc))) + return false; + hlsl_block_add_instr(params->instrs, deg); + + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg, deg, loc); +} + static bool intrinsic_ddy_fine(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -3865,6 +3881,7 @@ intrinsic_functions[] = {"ddy", 1, true, intrinsic_ddy}, {"ddy_coarse", 1, true, intrinsic_ddy_coarse}, {"ddy_fine", 1, true, intrinsic_ddy_fine}, + {"degrees", 1, true, intrinsic_degrees}, {"distance", 2, true, intrinsic_distance}, {"dot", 2, true, intrinsic_dot}, {"exp", 1, true, intrinsic_exp}, diff --git a/tests/hlsl/angle-unit.shader_test b/tests/hlsl/angle-unit.shader_test index 6e0538f98..407d24139 100644 --- a/tests/hlsl/angle-unit.shader_test +++ b/tests/hlsl/angle-unit.shader_test @@ -10,3 +10,17 @@ float4 main() : sv_target uniform 0 float4 0.0 30.0 150.0 180.0 draw quad probe all rgba (0.0, 0.52359877, 2.61799387, 3.14159265) + + +[pixel shader] +uniform float4 a; + +float4 main() : sv_target +{ + return degrees(a); +} + +[test] +uniform 0 float4 0.0 0.78539816 1.57079632 2.35619449 +draw quad +probe all rgba (0.0, 45.0, 90.0, 135.0)
I forgot `f` suffix in the degrees() patch. Fixed.
This merge request was approved by Giovanni Mascellani.
On Sun Nov 19 22:52:29 2023 +0000, Akihiro Sagawa wrote:
Thanks for comments. Yes, they're surely based on log/log10 functions. I'll add `hlsl_block_add_instr()` where needed.
Honestly, in general I think we can move towards replacing hlsl_new_* with hlsl_add_*. In the vast majority of cases (parsing and lowering passes) we're adding to an existing block, and we really want to lean in that direction anyway so we're not so much using list functions directly.
This merge request was approved by Zebediah Figura.
This is fine, but introduces new features and so may be deferred until after 1.10 at this point.
This is fine, but introduces new features and so may be deferred until after 1.10 at this point.
In principle, but I'm still willing to risk it.
This merge request was approved by Henri Verbeet.