From de6abd964e3e83b75395f230332140348a0e10a6 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Wed, 4 Sep 2024 13:19:16 +0200 Subject: [PATCH] vkd3d-shader/hlsl: Implement the mad() intrinsic. Signed-off-by: Nikolay Sivov --- libs/vkd3d-shader/hlsl.y | 15 +++++++++++++++ libs/vkd3d-shader/tpf.c | 17 +++++++++++++++++ tests/hlsl/arithmetic-float-uniform.shader_test | 10 +++++----- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 816d992a..38642025 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -4152,6 +4152,20 @@ static bool intrinsic_log2(struct hlsl_ctx *ctx, return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_LOG2, arg, loc); } +static bool intrinsic_mad(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; + + if (!elementwise_intrinsic_convert_args(ctx, params, loc)) + return false; + + args[0] = params->args[0]; + args[1] = params->args[1]; + args[2] = params->args[2]; + return add_expr(ctx, params->instrs, HLSL_OP3_MAD, args, args[0]->data_type, loc); +} + static bool intrinsic_max(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -5053,6 +5067,7 @@ intrinsic_functions[] = {"log", 1, true, intrinsic_log}, {"log10", 1, true, intrinsic_log10}, {"log2", 1, true, intrinsic_log2}, + {"mad", 3, true, intrinsic_mad}, {"max", 2, true, intrinsic_max}, {"min", 2, true, intrinsic_min}, {"mul", 2, true, intrinsic_mul}, diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index 8bb9ec24..b76a596b 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -5580,6 +5580,23 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex write_sm4_ternary_op(tpf, VKD3D_SM4_OP_MOVC, &expr->node, arg1, arg2, arg3); break; + case HLSL_OP3_MAD: + switch (dst_type->e.numeric.type) + { + case HLSL_TYPE_FLOAT: + write_sm4_ternary_op(tpf, VKD3D_SM4_OP_MAD, &expr->node, arg1, arg2, arg3); + break; + + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + write_sm4_ternary_op(tpf, VKD3D_SM4_OP_IMAD, &expr->node, arg1, arg2, arg3); + break; + + default: + hlsl_fixme(tpf->ctx, &expr->node.loc, "SM4 %s negation expression.", dst_type_string->buffer); + } + break; + default: hlsl_fixme(tpf->ctx, &expr->node.loc, "SM4 %s expression.", debug_hlsl_expr_op(expr->op)); } diff --git a/tests/hlsl/arithmetic-float-uniform.shader_test b/tests/hlsl/arithmetic-float-uniform.shader_test index 6cb9fd28..78da55fd 100644 --- a/tests/hlsl/arithmetic-float-uniform.shader_test +++ b/tests/hlsl/arithmetic-float-uniform.shader_test @@ -91,7 +91,7 @@ uniform 0 float4 1.0 0.0 0.0 0.0 todo(glsl) draw quad probe (0, 0) rgba (1e99, 1e99, 1e99, 1e99) -[pixel shader todo] +[pixel shader] uniform float4 a, b, c; float4 main() : sv_target @@ -103,11 +103,11 @@ float4 main() : sv_target uniform 0 float4 1.00000007 -42.1 4.0 45.0 uniform 4 float4 1.625 -5.0 4.125 5.0 uniform 8 float4 1.00000007 -1.0 0.5 -0.5 -todo(sm<6) draw quad +todo(glsl) draw quad probe (0, 0) rgba (2.62500024, 209.5, 17.0, 224.5) 1 % precise mad() is not allowed to fuse, even though unfused is less precise. -[pixel shader todo] +[pixel shader] uniform float4 a, b, c; float4 main() : sv_target @@ -120,8 +120,8 @@ float4 main() : sv_target uniform 0 float4 1.00000007 -42.1 4.0 45.0 uniform 4 float4 1.625 -5.0 4.125 5.0 uniform 8 float4 1.00000007 -1.0 0.5 -0.5 -todo(sm<6) draw quad -probe (0, 0) rgba (2.62500048, 209.5, 17.0, 224.5) +todo(glsl) draw quad +probe (0, 0) rgba (2.62500048, 209.5, 17.0, 224.5) 1 [require] shader model >= 5.0