Also, renaming `compatible_data_types()` to `explicit_compatible_data_types()` since we also have `implicit_compatible_data_types()` and `expr_compatible_data_types()`.
From: Francisco Casas fcasas@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;
From: Francisco Casas fcasas@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)
From: Francisco Casas fcasas@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)
From: Francisco Casas fcasas@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]
From: Francisco Casas fcasas@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)
From: Francisco Casas fcasas@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);
This merge request was approved by Zebediah Figura.
This merge request was approved by Giovanni Mascellani.
This merge request was approved by Henri Verbeet.