From 855b9713b85df931ad5169c254c409f5e98fcfaf Mon Sep 17 00:00:00 2001 From: Petrichor Park Date: Mon, 19 Aug 2024 12:57:50 -0500 Subject: [PATCH] vkd3d-shader/hlsl: Implement the sincos() intrinsic. --- libs/vkd3d-shader/hlsl.y | 30 ++++++++++++++++++ tests/hlsl/trigonometry.shader_test | 47 +++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 6c64a607..a5a4661f 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -4489,6 +4489,35 @@ static bool intrinsic_sin(struct hlsl_ctx *ctx, return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SIN, arg, loc); } +static bool intrinsic_sincos(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[] = + "void sincos(%s f, out %s s, out %s c)\n" + "{\n" + " s = sin(f);\n" + " c = cos(f);\n" + "}"; + + if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) + return false; + type = params->args[0]->data_type; + + if (!(body = hlsl_sprintf_alloc(ctx, template, + type->name, type->name, type->name))) + return false; + func = hlsl_compile_internal_function(ctx, "sincos", body); + vkd3d_free(body); + if (!func) + return false; + + return !!add_user_call(ctx, func, params, false, loc); +} + static bool intrinsic_sinh(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -5041,6 +5070,7 @@ intrinsic_functions[] = {"saturate", 1, true, intrinsic_saturate}, {"sign", 1, true, intrinsic_sign}, {"sin", 1, true, intrinsic_sin}, + {"sincos", 3, true, intrinsic_sincos}, {"sinh", 1, true, intrinsic_sinh}, {"smoothstep", 3, true, intrinsic_smoothstep}, {"sqrt", 1, true, intrinsic_sqrt}, diff --git a/tests/hlsl/trigonometry.shader_test b/tests/hlsl/trigonometry.shader_test index 86161e3d..6769886d 100644 --- a/tests/hlsl/trigonometry.shader_test +++ b/tests/hlsl/trigonometry.shader_test @@ -126,3 +126,50 @@ probe (0, 0) rgba (-0.91715234, -0.5, 0.5, 0.91715234) 2 uniform 0 float4 -10.0 -0.0 0.0 10.0 todo(glsl) draw quad probe (0, 0) rgba (-1.0, 0.0, 0.0, 1.0) 1 + + +[pixel shader] +uniform float4 a; + +float4 main() : sv_target +{ + float sin_out, cos_out; + sincos(a.x, sin_out, cos_out); + return float4(sin_out, cos_out, 0.0, 0.0); +} + +[test] +uniform 0 float4 7.604 0 0 0 +todo(glsl) draw quad +probe (0, 0) rgba (0.968916833, 0.2473865, 0, 0) 1024 +uniform 0 float4 -10.0 0 0 0 +todo(glsl) draw quad +probe (0, 0) rgba (0.544020891, -0.839071631, 0.0, 0.0) 1024 + +[pixel shader fail] +float4 main() : sv_target +{ + // Make sure `out` variables don't work with literals + sincos(12345.0, 10.0, 20.0); + return float4(6789); + +[pixel shader fail] +float4 main() : sv_target +{ + // sincos returns void. + float s, c; + float err = sincos(12345.0, s, c); + return float4(6789); +} + +[pixel shader todo] +float4 main() : sv_target +{ + int sin_out, cos_out; + sincos(30, sin_out, cos_out); + return float4(sin_out, cos_out, 0, 0); +} + +[test] +todo(sm<6 | glsl) draw quad +probe (0, 0) rgba (0, 0, 0, 0);