[PATCH vkd3d 2/5] vkd3d-shader: Apply type modifiers recursively when cloning a type.

Zebediah Figura zfigura at codeweavers.com
Wed Jun 23 23:57:32 CDT 2021


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 libs/vkd3d-shader/hlsl.c       | 16 ++++++++++++----
 libs/vkd3d-shader/hlsl.h       |  3 +--
 libs/vkd3d-shader/hlsl.y       | 20 +++-----------------
 tests/hlsl-invalid.shader_test | 14 ++++++++++++++
 4 files changed, 30 insertions(+), 23 deletions(-)

diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
index 721458eb..72703bc9 100644
--- a/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d-shader/hlsl.c
@@ -98,6 +98,13 @@ void hlsl_free_var(struct hlsl_ir_var *decl)
     vkd3d_free(decl);
 }
 
+static bool hlsl_type_is_row_major(const struct hlsl_type *type)
+{
+    /* Default to column-major if the majority isn't explicitly set, which can
+     * happen for anonymous nodes. */
+    return !!(type->modifiers & HLSL_MODIFIER_ROW_MAJOR);
+}
+
 struct hlsl_type *hlsl_new_type(struct hlsl_ctx *ctx, const char *name, enum hlsl_type_class type_class,
         enum hlsl_base_type base_type, unsigned dimx, unsigned dimy)
 {
@@ -276,7 +283,8 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2
     return true;
 }
 
-struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, unsigned int default_majority)
+struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old,
+        unsigned int default_majority, unsigned int modifiers)
 {
     struct hlsl_struct_field *old_field, *field;
     struct hlsl_type *type;
@@ -297,14 +305,14 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, u
     type->base_type = old->base_type;
     type->dimx = old->dimx;
     type->dimy = old->dimy;
-    type->modifiers = old->modifiers;
+    type->modifiers = old->modifiers | modifiers;
     if (!(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK))
         type->modifiers |= default_majority;
     type->sampler_dim = old->sampler_dim;
     switch (old->type)
     {
         case HLSL_CLASS_ARRAY:
-            type->e.array.type = hlsl_type_clone(ctx, old->e.array.type, default_majority);
+            type->e.array.type = hlsl_type_clone(ctx, old->e.array.type, default_majority, modifiers);
             type->e.array.elements_count = old->e.array.elements_count;
             type->reg_size = type->e.array.elements_count * type->e.array.type->reg_size;
             break;
@@ -336,7 +344,7 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, u
                     return NULL;
                 }
                 field->loc = old_field->loc;
-                field->type = hlsl_type_clone(ctx, old_field->type, default_majority);
+                field->type = hlsl_type_clone(ctx, old_field->type, default_majority, modifiers);
                 field->name = hlsl_strdup(ctx, old_field->name);
                 if (old_field->semantic.name)
                 {
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
index e2ac0a77..f461a07f 100644
--- a/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d-shader/hlsl.h
@@ -676,9 +676,8 @@ void hlsl_pop_scope(struct hlsl_ctx *ctx) DECLSPEC_HIDDEN;
 bool hlsl_scope_add_type(struct hlsl_scope *scope, struct hlsl_type *type) DECLSPEC_HIDDEN;
 
 struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old,
-        unsigned int default_majority) DECLSPEC_HIDDEN;
+        unsigned int default_majority, unsigned int modifiers) DECLSPEC_HIDDEN;
 unsigned int hlsl_type_component_count(struct hlsl_type *type) DECLSPEC_HIDDEN;
-bool hlsl_type_is_row_major(const struct hlsl_type *type) DECLSPEC_HIDDEN;
 bool hlsl_type_is_void(const struct hlsl_type *type) DECLSPEC_HIDDEN;
 bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2) DECLSPEC_HIDDEN;
 
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index 513c4512..34cdb543 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -624,13 +624,6 @@ static struct hlsl_struct_field *get_struct_field(struct list *fields, const cha
     return NULL;
 }
 
-bool hlsl_type_is_row_major(const struct hlsl_type *type)
-{
-    /* Default to column-major if the majority isn't explicitly set, which can
-     * happen for anonymous nodes. */
-    return !!(type->modifiers & HLSL_MODIFIER_ROW_MAJOR);
-}
-
 static struct hlsl_type *apply_type_modifiers(struct hlsl_ctx *ctx, struct hlsl_type *type,
         unsigned int *modifiers, struct vkd3d_shader_location loc)
 {
@@ -656,18 +649,15 @@ static struct hlsl_type *apply_type_modifiers(struct hlsl_ctx *ctx, struct hlsl_
     if (!default_majority && !(*modifiers & HLSL_TYPE_MODIFIERS_MASK))
         return type;
 
-    if (!(new_type = hlsl_type_clone(ctx, type, default_majority)))
+    if (!(new_type = hlsl_type_clone(ctx, type, default_majority, *modifiers & HLSL_TYPE_MODIFIERS_MASK)))
         return NULL;
 
-    new_type->modifiers |= *modifiers;
     *modifiers &= ~HLSL_TYPE_MODIFIERS_MASK;
 
     if ((new_type->modifiers & HLSL_MODIFIER_ROW_MAJOR) && (new_type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR))
         hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
                 "'row_major' and 'column_major' modifiers are mutually exclusive.");
 
-    if (new_type->type == HLSL_CLASS_MATRIX)
-        new_type->reg_size = (hlsl_type_is_row_major(new_type) ? new_type->dimy : new_type->dimx) * 4;
     return new_type;
 }
 
@@ -721,7 +711,7 @@ static bool add_typedef(struct hlsl_ctx *ctx, DWORD modifiers, struct hlsl_type
     {
         if (!v->arrays.count)
         {
-            if (!(type = hlsl_type_clone(ctx, orig_type, 0)))
+            if (!(type = hlsl_type_clone(ctx, orig_type, 0, modifiers)))
                 return false;
         }
         else
@@ -737,12 +727,9 @@ static bool add_typedef(struct hlsl_ctx *ctx, DWORD modifiers, struct hlsl_type
 
         vkd3d_free((void *)type->name);
         type->name = v->name;
-        type->modifiers |= modifiers;
 
         if (type->type != HLSL_CLASS_MATRIX)
             check_invalid_matrix_modifiers(ctx, type->modifiers, v->loc);
-        else
-            type->reg_size = (hlsl_type_is_row_major(type) ? type->dimy : type->dimx) * 4;
 
         if ((type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR)
                 && (type->modifiers & HLSL_MODIFIER_ROW_MAJOR))
@@ -1294,9 +1281,8 @@ static bool add_increment(struct hlsl_ctx *ctx, struct list *instrs, bool decrem
         list_add_tail(instrs, &copy->node.entry);
 
         /* Post increment/decrement expressions are considered const. */
-        if (!(copy->node.data_type = hlsl_type_clone(ctx, copy->node.data_type, 0)))
+        if (!(copy->node.data_type = hlsl_type_clone(ctx, copy->node.data_type, 0, HLSL_MODIFIER_CONST)))
             return false;
-        copy->node.data_type->modifiers |= HLSL_MODIFIER_CONST;
     }
 
     return true;
diff --git a/tests/hlsl-invalid.shader_test b/tests/hlsl-invalid.shader_test
index f6a7ffd3..a7364b1e 100644
--- a/tests/hlsl-invalid.shader_test
+++ b/tests/hlsl-invalid.shader_test
@@ -236,3 +236,17 @@ float4 main() : sv_target
 {
     return float4(0, 0, 0, 0);
 }
+
+[pixel shader fail]
+typedef struct apple
+{
+    float a;
+} apple_t;
+
+uniform const apple_t a;
+
+float4 main() : sv_target
+{
+    a.a = 1;
+    return a.a;
+}
-- 
2.32.0




More information about the wine-devel mailing list