-- v4: vkd3d-shader/hlsl: Support distance() intrinsic.
From: Nikolay Sivov nsivov@codeweavers.com
--- libs/vkd3d-shader/hlsl.y | 12 ++++++++++++ tests/sqrt.shader_test | 13 +++++++++++++ 2 files changed, 25 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index a4de0edd..71eedfa5 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2778,6 +2778,17 @@ static bool intrinsic_round(struct hlsl_ctx *ctx, return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_ROUND, arg, loc); }
+static bool intrinsic_rsqrt(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg; + + if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + return false; + + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_RSQ, arg, loc); +} + static bool intrinsic_saturate(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -2976,6 +2987,7 @@ intrinsic_functions[] = {"normalize", 1, true, intrinsic_normalize}, {"pow", 2, true, intrinsic_pow}, {"round", 1, true, intrinsic_round}, + {"rsqrt", 1, true, intrinsic_rsqrt}, {"saturate", 1, true, intrinsic_saturate}, {"sin", 1, true, intrinsic_sin}, {"smoothstep", 3, true, intrinsic_smoothstep}, diff --git a/tests/sqrt.shader_test b/tests/sqrt.shader_test index 5d048b4f..78d89d38 100644 --- a/tests/sqrt.shader_test +++ b/tests/sqrt.shader_test @@ -10,3 +10,16 @@ float4 main() : sv_target uniform 0 float4 1.0 9.0 32.3 46.5 draw quad probe all rgba (1.0, 3.0, 5.683309, 6.819091) 1 + +[pixel shader] +uniform float4 f; + +float4 main() : sv_target +{ + return rsqrt(f); +} + +[test] +uniform 0 float4 1.0 9.0 4.0 16.0 +draw quad +probe all rgba (1.0, 0.33333333, 0.5, 0.25) 1
From: Nikolay Sivov nsivov@codeweavers.com
--- Makefile.am | 1 + libs/vkd3d-shader/hlsl.y | 18 ++++++++++++++++++ tests/distance.shader_test | 14 ++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 tests/distance.shader_test
diff --git a/Makefile.am b/Makefile.am index f9199472..822906c8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -59,6 +59,7 @@ vkd3d_shader_tests = \ tests/cbuffer.shader_test \ tests/compute.shader_test \ tests/conditional.shader_test \ + tests/distance.shader_test \ tests/entry-point-semantics.shader_test \ tests/exp.shader_test \ tests/floor.shader_test \ diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 71eedfa5..d9cb6546 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2485,6 +2485,23 @@ static bool intrinsic_cross(struct hlsl_ctx *ctx, return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, mul2, mul1_neg, loc); }
+static bool intrinsic_distance(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *neg, *add, *dot; + + if (!(neg = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_NEG, params->args[1], loc))) + return false; + + if (!(add = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, params->args[0], neg, loc))) + return false; + + if (!(dot = add_binary_dot_expr(ctx, params->instrs, add, add, loc))) + return false; + + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SQRT, dot, loc); +} + static bool intrinsic_dot(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -2973,6 +2990,7 @@ intrinsic_functions[] = {"clamp", 3, true, intrinsic_clamp}, {"cos", 1, true, intrinsic_cos}, {"cross", 2, true, intrinsic_cross}, + {"distance", 2, true, intrinsic_distance}, {"dot", 2, true, intrinsic_dot}, {"exp", 1, true, intrinsic_exp}, {"exp2", 1, true, intrinsic_exp2}, diff --git a/tests/distance.shader_test b/tests/distance.shader_test new file mode 100644 index 00000000..39c23eaf --- /dev/null +++ b/tests/distance.shader_test @@ -0,0 +1,14 @@ +[pixel shader] +uniform float4 x; +uniform float4 y; + +float4 main() : sv_target +{ + return distance(x, y); +} + +[test] +uniform 0 float4 -2.0 3.0 4.0 0.1 +uniform 1 float4 2.0 -1.0 4.0 5.0 +draw quad +probe all rgba (8.3666, 8.3666, 8.3666, 8.3666) 1
On Wed Feb 1 13:25:25 2023 +0000, Nikolay Sivov wrote:
changed this line in [version 4 of the diff](/wine/vkd3d/-/merge_requests/76/diffs?diff_id=30354&start_sha=7b28929e1f239d59179737cbafd12bb4d0384c31#9155b9453b4ec8ea0b9b025dfb55c061bd931610_2494_2493)
Thanks, I removed conversion part.
The distance() test is failing for me with d3d11 + Wine. It looks like a mesa bug; I'm looking into it.
Well, for one, 8.3666 is wrong, the result should be 7.48398304. I'm getting intermittent failures with even very simple shaders, though, which is very weird.
I'm annoyed at how long it took me to notice this, but the second line is "uniform 1", not "uniform 4", so that's where the uninitialized values are coming from.
Oh, sorry about that. I didn't know it's counted in floats.