diff --git a/Makefile.am b/Makefile.am index 921702b9..f6e105e0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -176,6 +176,7 @@ vkd3d_shader_tests = \ tests/hlsl/matrix-semantics.shader_test \ tests/hlsl/max-min.shader_test \ tests/hlsl/minimum-precision.shader_test \ + tests/hlsl/modf.shader_test \ tests/hlsl/mul.shader_test \ tests/hlsl/multiple-rt.shader_test \ tests/hlsl/nested-arrays.shader_test \ diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 2230cd5b..da8a1b87 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -4260,6 +4260,35 @@ static bool intrinsic_min(struct hlsl_ctx *ctx, return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MIN, params->args[0], params->args[1], loc); } +static bool intrinsic_modf(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 modf(%s x, out %s ip)\n" + "{\n" + " ip = trunc(x);\n" + " return x - ip;\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, "modf", body); + vkd3d_free(body); + if (!func) + return false; + + return !!add_user_call(ctx, func, params, false, loc); +} + static bool intrinsic_mul(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -5147,6 +5176,7 @@ intrinsic_functions[] = {"mad", 3, true, intrinsic_mad}, {"max", 2, true, intrinsic_max}, {"min", 2, true, intrinsic_min}, + {"modf", 2, true, intrinsic_modf}, {"mul", 2, true, intrinsic_mul}, {"normalize", 1, true, intrinsic_normalize}, {"pow", 2, true, intrinsic_pow}, diff --git a/tests/hlsl/modf.shader_test b/tests/hlsl/modf.shader_test new file mode 100644 index 00000000..5a7dc407 --- /dev/null +++ b/tests/hlsl/modf.shader_test @@ -0,0 +1,28 @@ +[pixel shader todo(sm<4)] +float4 v; + +float4 main() : sv_target +{ + float4 ip; + return modf(v, ip); +} + +[test] +uniform 0 float4 1.2 1.7 -1.2 -1.7 +todo(sm<4) draw quad +probe (0, 0) rgba (0.2, 0.7, -0.2, -0.7) 4 + +[pixel shader todo(sm<4)] +float4 v; + +float4 main() : sv_target +{ + float4 ip; + modf(v, ip); + return ip; +} + +[test] +uniform 0 float4 1.2 2.7 -1.2 -2.7 +todo(sm<4) draw quad +probe (0, 0) rgba (1.0, 2.0, -1.0, -2.0)