From: Nikolay Sivov nsivov@codeweavers.com
--- Makefile.am | 1 + libs/vkd3d-shader/hlsl.y | 25 +++++++++++++++++++++++++ tests/reflect.shader_test | 11 +++++++++++ 3 files changed, 37 insertions(+) create mode 100644 tests/reflect.shader_test
diff --git a/Makefile.am b/Makefile.am index f9199472..8822e9eb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -130,6 +130,7 @@ vkd3d_shader_tests = \ tests/preproc-invalid.shader_test \ tests/preproc-macro.shader_test \ tests/preproc-misc.shader_test \ + tests/reflect.shader_test \ tests/return.shader_test \ tests/round.shader_test \ tests/sampler.shader_test \ diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index a4de0edd..db7bbde6 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2767,6 +2767,30 @@ static bool intrinsic_pow(struct hlsl_ctx *ctx, return true; }
+static bool intrinsic_reflect(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *i = params->args[0], *n = params->args[1]; + struct hlsl_ir_node *dot, *mul_n, *two_dot, *neg; + + if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) + return false; + + if (!(dot = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_DOT, i, n, loc))) + return false; + + if (!(two_dot = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, dot, dot, loc))) + return false; + + if (!(mul_n = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, n, two_dot, loc))) + return false; + + if (!(neg = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_NEG, mul_n, loc))) + return false; + + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, i, neg, loc); +} + static bool intrinsic_round(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -2975,6 +2999,7 @@ intrinsic_functions[] = {"mul", 2, true, intrinsic_mul}, {"normalize", 1, true, intrinsic_normalize}, {"pow", 2, true, intrinsic_pow}, + {"reflect", 2, true, intrinsic_reflect}, {"round", 1, true, intrinsic_round}, {"saturate", 1, true, intrinsic_saturate}, {"sin", 1, true, intrinsic_sin}, diff --git a/tests/reflect.shader_test b/tests/reflect.shader_test new file mode 100644 index 00000000..a5746599 --- /dev/null +++ b/tests/reflect.shader_test @@ -0,0 +1,11 @@ +[pixel shader] +float4 main(uniform float4 i, uniform float4 n) : sv_target +{ + return reflect(i, n); +} + +[test] +uniform 0 float4 0.5 -0.1 0.2 0.3 +uniform 1 float4 0.6 0.4 -0.3 1.0 +draw quad +probe all rgba (-0.5, 0.6, 0.4, -0.3)