Module: vkd3d Branch: master Commit: b3c620954b2d20411c31f806659bcd7aa842c517 URL: https://gitlab.winehq.org/wine/vkd3d/-/commit/b3c620954b2d20411c31f806659bcd...
Author: Zebediah Figura zfigura@codeweavers.com Date: Wed Feb 15 18:07:33 2023 -0600
vkd3d-shader/hlsl: Apply latent type modifiers to matrix array typedefs.
---
libs/vkd3d-shader/hlsl.y | 25 ++++++++++--------- tests/hlsl-majority-pragma.shader_test | 45 ++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 11 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 4b26a179..c187cc47 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -882,12 +882,6 @@ static struct hlsl_type *apply_type_modifiers(struct hlsl_ctx *ctx, struct hlsl_ unsigned int default_majority = 0; struct hlsl_type *new_type;
- /* This function is only used for declarations (i.e. variables and struct - * fields), which should inherit the matrix majority. We only explicitly set - * the default majority for declarations—typedefs depend on this—but we - * want to always set it, so that an hlsl_type object is never used to - * represent two different majorities (and thus can be used to store its - * register size, etc.) */ if (!(*modifiers & HLSL_MODIFIERS_MAJORITY_MASK) && !(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK) && type->type == HLSL_CLASS_MATRIX) @@ -1003,7 +997,8 @@ static bool gen_struct_fields(struct hlsl_ctx *ctx, struct parse_fields *fields, return true; }
-static bool add_typedef(struct hlsl_ctx *ctx, DWORD modifiers, struct hlsl_type *orig_type, struct list *list) +static bool add_typedef(struct hlsl_ctx *ctx, const unsigned int modifiers, + struct hlsl_type *const orig_type, struct list *list) { struct parse_variable_def *v, *v_next; struct hlsl_type *type; @@ -1014,15 +1009,26 @@ static bool add_typedef(struct hlsl_ctx *ctx, DWORD modifiers, struct hlsl_type { if (!v->arrays.count) { + /* Do not use apply_type_modifiers() here. We should not apply the + * latent matrix majority to plain matrix types. */ if (!(type = hlsl_type_clone(ctx, orig_type, 0, modifiers))) { free_parse_variable_def(v); continue; } + + if (type->type != HLSL_CLASS_MATRIX) + check_invalid_matrix_modifiers(ctx, modifiers, v->loc); } else { - type = orig_type; + unsigned int var_modifiers = modifiers; + + if (!(type = apply_type_modifiers(ctx, orig_type, &var_modifiers, v->loc))) + { + free_parse_variable_def(v); + continue; + } }
ret = true; @@ -1048,9 +1054,6 @@ static bool add_typedef(struct hlsl_ctx *ctx, DWORD modifiers, struct hlsl_type vkd3d_free((void *)type->name); type->name = v->name;
- if (type->type != HLSL_CLASS_MATRIX) - check_invalid_matrix_modifiers(ctx, type->modifiers, v->loc); - if ((type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR) && (type->modifiers & HLSL_MODIFIER_ROW_MAJOR)) hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, diff --git a/tests/hlsl-majority-pragma.shader_test b/tests/hlsl-majority-pragma.shader_test index da1b1ff3..48915aa7 100644 --- a/tests/hlsl-majority-pragma.shader_test +++ b/tests/hlsl-majority-pragma.shader_test @@ -128,6 +128,31 @@ float4 main() : sv_target }
+% This applies to arrays as well. Note that struct fields already have latent +% majority applied (even if there have been no pragmas, as shown below), so the +% question of typedefs is moot there. + + +[pixel shader] +#pragma pack_matrix(row_major) +typedef float2x2 myarray_t[2]; +#pragma pack_matrix(column_major) +uniform myarray_t a; + +float4 main() : sv_target +{ + return float4(a[0][0], a[1][1]); +} + +[test] +uniform 0 float4 0.3 0.4 0.0 0.0 +uniform 4 float4 0.0 0.0 0.0 0.0 +uniform 8 float4 0.0 0.0 0.0 0.0 +uniform 12 float4 0.5 0.6 0.0 0.0 +draw quad +probe all rgba (0.3, 0.4, 0.5, 0.6) + + % However, if no pack_matrix directive has been used yet, a typedef has no % defined majority, and the majority can be overwritten, including by a % subsequent pragma. @@ -178,3 +203,23 @@ uniform 0 float4 0.2 0.4 0.0 0.0 uniform 4 float4 0.3 0.5 0.0 0.0 draw quad probe all rgba (0.2, 0.3, 0.4, 0.5) + + +[pixel shader] +typedef float2x2 myarray_t[2]; +#pragma pack_matrix(row_major) +typedef myarray_t myarray2_t; +uniform myarray2_t a; + +float4 main() : sv_target +{ + return float4(a[0][0], a[1][1]); +} + +[test] +uniform 0 float4 0.3 0.0 0.0 0.0 +uniform 4 float4 0.4 0.0 0.0 0.0 +uniform 8 float4 0.0 0.5 0.0 0.0 +uniform 12 float4 0.0 0.6 0.0 0.0 +draw quad +probe all rgba (0.3, 0.4, 0.5, 0.6)