[PATCH 0/6] MR99: vkd3d-shader/hlsl: Array parameters and support for a single compatible function overload.
Also, renaming `compatible_data_types()` to `explicit_compatible_data_types()` since we also have `implicit_compatible_data_types()` and `expr_compatible_data_types()`. -- https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/99
From: Francisco Casas <fcasas(a)codeweavers.com> --- libs/vkd3d-shader/hlsl.y | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 76b0eae7..47f0d98d 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -217,7 +217,7 @@ static bool type_contains_only_numerics(struct hlsl_type *type) return type->type <= HLSL_CLASS_LAST_NUMERIC; } -static bool compatible_data_types(struct hlsl_ctx *ctx, struct hlsl_type *src, struct hlsl_type *dst) +static bool explicit_compatible_data_types(struct hlsl_ctx *ctx, struct hlsl_type *src, struct hlsl_type *dst) { if (src->type <= HLSL_CLASS_LAST_NUMERIC && src->dimx == 1 && src->dimy == 1 && type_contains_only_numerics(dst)) return true; @@ -5189,7 +5189,7 @@ unary_expr: dst_type = hlsl_new_array_type(ctx, dst_type, $4.sizes[i]); } - if (!compatible_data_types(ctx, src_type, dst_type)) + if (!explicit_compatible_data_types(ctx, src_type, dst_type)) { struct vkd3d_string_buffer *src_string, *dst_string; -- GitLab https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/99
From: Francisco Casas <fcasas(a)codeweavers.com> --- tests/cast-broadcast.shader_test | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/cast-broadcast.shader_test b/tests/cast-broadcast.shader_test index d8571fc8..a7462e76 100644 --- a/tests/cast-broadcast.shader_test +++ b/tests/cast-broadcast.shader_test @@ -55,6 +55,18 @@ float4 main() : SV_TARGET } +[pixel shader fail] +float4 fun(float f[7]) +{ + return f[1]; +} + +float4 main() : SV_TARGET +{ + return fun(32); +} + + [pixel shader fail] struct apple { @@ -68,3 +80,19 @@ float4 PSMain() : SV_TARGET a1 = (struct apple)1; return a1.foo; } + + +[pixel shader todo] +float4 fun(float3 f) +{ + return f.xyxy; +} + +float4 main() : SV_TARGET +{ + return fun(33); +} + +[test] +todo draw quad +todo probe all rgba (33.0, 33.0, 33.0, 33.0) -- GitLab https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/99
From: Francisco Casas <fcasas(a)codeweavers.com> --- Makefile.am | 1 + tests/array-parameters.shader_test | 161 +++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100644 tests/array-parameters.shader_test diff --git a/Makefile.am b/Makefile.am index f9199472..d422d0c2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -48,6 +48,7 @@ vkd3d_shader_tests = \ tests/arithmetic-int.shader_test \ tests/arithmetic-int-uniform.shader_test \ tests/arithmetic-uint.shader_test \ + tests/array-parameters.shader_test \ tests/bitwise.shader_test \ tests/cast-broadcast.shader_test \ tests/cast-componentwise-equal.shader_test \ diff --git a/tests/array-parameters.shader_test b/tests/array-parameters.shader_test new file mode 100644 index 00000000..615aa3f4 --- /dev/null +++ b/tests/array-parameters.shader_test @@ -0,0 +1,161 @@ +[pixel shader todo] +float fun(float a[2]) +{ + return 10 * a[0] + a[1]; +} + +float4 main() : sv_target +{ + float f[2] = {2, 5}; + + return fun(f); +} + +[test] +todo draw quad +todo probe all rgba (25.0, 25.0, 25.0, 25.0) + + +[pixel shader fail] +float fun(float a[2]) +{ + return 0; +} + +float4 main() : sv_target +{ + int f[2] = {2, 5}; + + return fun(f); +} + + +[pixel shader fail] +float fun(float a[1]) +{ + return 0; +} + +float4 main() : sv_target +{ + float f = 4; + + return fun(f); +} + + +[pixel shader fail] +float fun(int a[2]) +{ + return 0; +} + +float4 main() : sv_target +{ + float f[2] = {1, 2}; + + return fun(f); +} + + +[pixel shader todo] +float4 fun(float a[2][4]) +{ + float4 res; + + res.x = 10 * a[0][0] + a[1][0]; + res.y = 10 * a[0][1] + a[1][1]; + res.z = 10 * a[0][2] + a[1][2]; + res.w = 10 * a[0][3] + a[1][3]; + return res; +} + +float4 main() : sv_target +{ + float f[2][4] = {1, 2, 3, 4, 5, 6, 7, 8}; + + return fun(f); +} + +[test] +todo draw quad +todo probe all rgba (15.0, 26.0, 37.0, 48.0) + + +[pixel shader fail] +float fun(float a[2]) +{ + return 0; +} + +float4 main() : sv_target +{ + float f[3] = {1, 2, 3}; + + return fun(f); +} + + +% Implicit size arrays are not allowed. +[pixel shader fail] +float fun(float a[]) +{ + return 0; +} + +float4 main() : sv_target +{ + float f[2] = {1, 2}; + + return fun(f); +} + +[pixel shader fail] +float4 fun(float a[4]) +{ + return 0; +} + +float4 main() : sv_target +{ + float4 v = {1, 2, 3, 4}; + + return fun(v); +} + + +% Arrays with the same number of components are allowed. +[pixel shader todo] +float fun(float a[2][3]) +{ + return 100*a[0][0] + 10*a[0][2] + a[1][2]; +} + +float4 main() : sv_target +{ + float f[3][2] = {1, 2, 3, 4, 5, 6}; + + return fun(f); +} + +[test] +todo draw quad +todo probe all rgba (136.0, 136.0, 136.0, 136.0) + + +[pixel shader todo] +float fun(float a[2][3]) +{ + return 100*a[0][0] + 10*a[1][0] + a[1][2]; +} + +float4 main() : sv_target +{ + float f[6] = {7, 8, 9, 0, 1, 2}; + + return fun(f); +} + +[test] +todo draw quad +todo probe all rgba (702.0, 702.0, 702.0, 702.0) -- GitLab https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/99
From: Francisco Casas <fcasas(a)codeweavers.com> --- libs/vkd3d-shader/hlsl.y | 20 ++++++++++++++++---- tests/array-parameters.shader_test | 26 ++++++++++++++++++++------ 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 47f0d98d..c22c0526 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -4266,10 +4266,11 @@ param_list: } parameter: - var_modifiers type_no_void any_identifier colon_attribute + var_modifiers type_no_void any_identifier arrays colon_attribute { - struct hlsl_type *type; unsigned int modifiers = $1; + struct hlsl_type *type; + unsigned int i; if (!(type = apply_type_modifiers(ctx, $2, &modifiers, @1))) YYABORT; @@ -4277,10 +4278,21 @@ parameter: $$.modifiers = modifiers; if (!($$.modifiers & (HLSL_STORAGE_IN | HLSL_STORAGE_OUT))) $$.modifiers |= HLSL_STORAGE_IN; + + for (i = 0; i < $4.count; ++i) + { + if ($4.sizes[i] == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT) + { + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Implicit size arrays not allowed in function parameters."); + } + type = hlsl_new_array_type(ctx, type, $4.sizes[i]); + } $$.type = type; + $$.name = $3; - $$.semantic = $4.semantic; - $$.reg_reservation = $4.reg_reservation; + $$.semantic = $5.semantic; + $$.reg_reservation = $5.reg_reservation; } texture_type: diff --git a/tests/array-parameters.shader_test b/tests/array-parameters.shader_test index 615aa3f4..3b7d628d 100644 --- a/tests/array-parameters.shader_test +++ b/tests/array-parameters.shader_test @@ -1,4 +1,4 @@ -[pixel shader todo] +[pixel shader] float fun(float a[2]) { return 10 * a[0] + a[1]; @@ -12,8 +12,8 @@ float4 main() : sv_target } [test] -todo draw quad -todo probe all rgba (25.0, 25.0, 25.0, 25.0) +draw quad +probe all rgba (25.0, 25.0, 25.0, 25.0) [pixel shader fail] @@ -58,7 +58,7 @@ float4 main() : sv_target } -[pixel shader todo] +[pixel shader] float4 fun(float a[2][4]) { float4 res; @@ -78,8 +78,22 @@ float4 main() : sv_target } [test] -todo draw quad -todo probe all rgba (15.0, 26.0, 37.0, 48.0) +draw quad +probe all rgba (15.0, 26.0, 37.0, 48.0) + + +[pixel shader fail] +float fun(float a[2]) +{ + return a[2]; // out of bounds. +} + +float4 main() : sv_target +{ + float f[2] = {1, 2}; + + return fun(f); +} [pixel shader fail] -- GitLab https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/99
From: Francisco Casas <fcasas(a)codeweavers.com> But still throw hlsl_fixme() when there is more than one. Prioritizing among multiple compatible function overloads in the same way as the native compiler would require systematic testing. --- libs/vkd3d-shader/hlsl.y | 45 +++++++++++++++++++--- tests/array-parameters.shader_test | 12 +++--- tests/cast-broadcast.shader_test | 6 +-- tests/cast-componentwise-equal.shader_test | 6 +-- tests/hlsl-intrinsic-override.shader_test | 10 ++--- 5 files changed, 56 insertions(+), 23 deletions(-) diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index c22c0526..fdf4db79 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2223,8 +2223,10 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t struct find_function_call_args { + struct hlsl_ctx *ctx; const struct parse_initializer *params; struct hlsl_ir_function_decl *decl; + unsigned int compatible_overloads_count; }; static void find_function_call_exact(struct rb_entry *entry, void *context) @@ -2244,10 +2246,31 @@ static void find_function_call_exact(struct rb_entry *entry, void *context) args->decl = decl; } +static void find_function_call_compatible(struct rb_entry *entry, void *context) +{ + struct hlsl_ir_function_decl *decl = RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry); + struct find_function_call_args *args = context; + unsigned int i; + + if (decl->parameters.count != args->params->args_count) + return; + + for (i = 0; i < decl->parameters.count; ++i) + { + if (!implicit_compatible_data_types(args->ctx, args->params->args[i]->data_type, + decl->parameters.vars[i]->data_type)) + return; + } + + args->compatible_overloads_count++; + args->decl = decl; +} + static struct hlsl_ir_function_decl *find_function_call(struct hlsl_ctx *ctx, - const char *name, const struct parse_initializer *params) + const char *name, const struct parse_initializer *params, + const struct vkd3d_shader_location *loc) { - struct find_function_call_args args = {.params = params}; + struct find_function_call_args args = {.ctx = ctx, .params = params}; struct hlsl_ir_function *func; struct rb_entry *entry; @@ -2257,7 +2280,13 @@ static struct hlsl_ir_function_decl *find_function_call(struct hlsl_ctx *ctx, rb_for_each_entry(&func->overloads, find_function_call_exact, &args); if (!args.decl) - FIXME("Search for compatible overloads.\n"); + { + rb_for_each_entry(&func->overloads, find_function_call_compatible, &args); + if (args.compatible_overloads_count > 1) + { + hlsl_fixme(ctx, loc, "Prioritize between multiple compatible function overloads."); + } + } return args.decl; } @@ -3004,7 +3033,7 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, struct intrinsic_function *intrinsic; struct hlsl_ir_function_decl *decl; - if ((decl = find_function_call(ctx, name, args))) + if ((decl = find_function_call(ctx, name, args, loc))) { struct hlsl_ir_node *call; unsigned int i; @@ -3018,8 +3047,12 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, if (!hlsl_types_are_equal(arg->data_type, param->data_type)) { - hlsl_fixme(ctx, &arg->loc, "Implicit cast of a function argument."); - continue; + struct hlsl_ir_node *cast; + + if (!(cast = add_cast(ctx, args->instrs, arg, param->data_type, &arg->loc))) + goto fail; + args->args[i] = cast; + arg = cast; } if (param->storage_modifiers & HLSL_STORAGE_IN) diff --git a/tests/array-parameters.shader_test b/tests/array-parameters.shader_test index 3b7d628d..6e866ceb 100644 --- a/tests/array-parameters.shader_test +++ b/tests/array-parameters.shader_test @@ -139,7 +139,7 @@ float4 main() : sv_target % Arrays with the same number of components are allowed. -[pixel shader todo] +[pixel shader] float fun(float a[2][3]) { return 100*a[0][0] + 10*a[0][2] + a[1][2]; @@ -153,11 +153,11 @@ float4 main() : sv_target } [test] -todo draw quad -todo probe all rgba (136.0, 136.0, 136.0, 136.0) +draw quad +probe all rgba (136.0, 136.0, 136.0, 136.0) -[pixel shader todo] +[pixel shader] float fun(float a[2][3]) { return 100*a[0][0] + 10*a[1][0] + a[1][2]; @@ -171,5 +171,5 @@ float4 main() : sv_target } [test] -todo draw quad -todo probe all rgba (702.0, 702.0, 702.0, 702.0) +draw quad +probe all rgba (702.0, 702.0, 702.0, 702.0) diff --git a/tests/cast-broadcast.shader_test b/tests/cast-broadcast.shader_test index a7462e76..3ec9cd40 100644 --- a/tests/cast-broadcast.shader_test +++ b/tests/cast-broadcast.shader_test @@ -82,7 +82,7 @@ float4 PSMain() : SV_TARGET } -[pixel shader todo] +[pixel shader] float4 fun(float3 f) { return f.xyxy; @@ -94,5 +94,5 @@ float4 main() : SV_TARGET } [test] -todo draw quad -todo probe all rgba (33.0, 33.0, 33.0, 33.0) +draw quad +probe all rgba (33.0, 33.0, 33.0, 33.0) diff --git a/tests/cast-componentwise-equal.shader_test b/tests/cast-componentwise-equal.shader_test index 7fe9304b..4a25f6dd 100644 --- a/tests/cast-componentwise-equal.shader_test +++ b/tests/cast-componentwise-equal.shader_test @@ -124,7 +124,7 @@ draw quad probe all rgba (4.0, 4.0, 4.0, 4.0) -[pixel shader todo] +[pixel shader] Texture2D tex; struct apple @@ -154,8 +154,8 @@ float4 main() : sv_target } [test] -todo draw quad -todo probe all rgba (5.0, 5.0, 5.0, 5.0) +draw quad +probe all rgba (5.0, 5.0, 5.0, 5.0) [pixel shader] diff --git a/tests/hlsl-intrinsic-override.shader_test b/tests/hlsl-intrinsic-override.shader_test index f9233a5c..13e1752d 100644 --- a/tests/hlsl-intrinsic-override.shader_test +++ b/tests/hlsl-intrinsic-override.shader_test @@ -1,4 +1,4 @@ -[pixel shader todo] +[pixel shader] float2 max(float2 a, float2 b) { @@ -11,10 +11,10 @@ float4 main() : sv_target } [test] -todo draw quad -probe all rgba (0.3, 0.3, 0.4, 0.6) +draw quad +todo probe all rgba (0.3, 0.3, 0.4, 0.6) -[pixel shader todo] +[pixel shader] float2 max(float2 a, float3 b) { @@ -27,5 +27,5 @@ float4 main() : sv_target } [test] -todo draw quad +draw quad probe all rgba (0.3, 0.3, 0.3, 0.4) -- GitLab https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/99
From: Francisco Casas <fcasas(a)codeweavers.com> --- libs/vkd3d-shader/hlsl.y | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index fdf4db79..f21789f0 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3143,6 +3143,12 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, if (!intrinsic->handler(ctx, args, loc)) goto fail; } + else if (rb_get(&ctx->functions, name)) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "No compatible %u parameter declaration for \"%s\" found.", + args->args_count, name); + goto fail; + } else { hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Function \"%s\" is not defined.", name); -- GitLab https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/99
This merge request was approved by Zebediah Figura. -- https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/99
This merge request was approved by Giovanni Mascellani. -- https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/99
This merge request was approved by Henri Verbeet. -- https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/99
participants (5)
-
Francisco Casas -
Francisco Casas (@fcasas) -
Giovanni Mascellani (@giomasce) -
Henri Verbeet (@hverbeet) -
Zebediah Figura (@zfigura)