Module: vkd3d
Branch: master
Commit: b3c620954b2d20411c31f806659bcd7aa842c517
URL:
https://gitlab.winehq.org/wine/vkd3d/-/commit/b3c620954b2d20411c31f806659bc…
Author: Zebediah Figura <zfigura(a)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)