[PATCH v2 3/4] d3dcompiler: Always set the matrix majority for declaration types.

Zebediah Figura z.figura12 at gmail.com
Thu Apr 2 16:14:12 CDT 2020


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
Ultimately, the difficulty is that the default majority is syntactically a
property of the declaration, but semantically a property of the type. I had to
play around with various solutions before settling on this one, which seems to
make things easiest for RA and reflection without breaking typedefs.

 dlls/d3dcompiler_43/d3dcompiler_private.h |  2 +-
 dlls/d3dcompiler_43/hlsl.y                | 39 +++++++++++++++++++----
 dlls/d3dcompiler_43/utils.c               |  8 +++--
 3 files changed, 39 insertions(+), 10 deletions(-)

diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h
index df45a7082fe..40c4fcffee5 100644
--- a/dlls/d3dcompiler_43/d3dcompiler_private.h
+++ b/dlls/d3dcompiler_43/d3dcompiler_private.h
@@ -1081,7 +1081,7 @@ void free_declaration(struct hlsl_ir_var *decl) DECLSPEC_HIDDEN;
 struct hlsl_type *new_hlsl_type(const char *name, enum hlsl_type_class type_class,
         enum hlsl_base_type base_type, unsigned dimx, unsigned dimy) DECLSPEC_HIDDEN;
 struct hlsl_type *new_array_type(struct hlsl_type *basic_type, unsigned int array_size) DECLSPEC_HIDDEN;
-struct hlsl_type *clone_hlsl_type(struct hlsl_type *old) DECLSPEC_HIDDEN;
+struct hlsl_type *clone_hlsl_type(struct hlsl_type *old, unsigned int default_majority) DECLSPEC_HIDDEN;
 struct hlsl_type *get_type(struct hlsl_scope *scope, const char *name, BOOL recursive) DECLSPEC_HIDDEN;
 BOOL find_function(const char *name) DECLSPEC_HIDDEN;
 unsigned int components_count_type(struct hlsl_type *type) DECLSPEC_HIDDEN;
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y
index 5381fa211a2..833472a351b 100644
--- a/dlls/d3dcompiler_43/hlsl.y
+++ b/dlls/d3dcompiler_43/hlsl.y
@@ -576,6 +576,9 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers,
     BOOL ret, local = TRUE;
     struct list *statements_list = d3dcompiler_alloc(sizeof(*statements_list));
 
+    if (basic_type->type == HLSL_CLASS_MATRIX)
+        assert(basic_type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
+
     if (!statements_list)
     {
         ERR("Out of memory.\n");
@@ -717,14 +720,32 @@ static BOOL add_struct_field(struct list *fields, struct hlsl_struct_field *fiel
     return TRUE;
 }
 
-static struct hlsl_type *apply_type_modifiers(struct hlsl_type *type, DWORD *modifiers, struct source_location loc)
+static struct hlsl_type *apply_type_modifiers(struct hlsl_type *type,
+        unsigned int *modifiers, struct source_location loc)
 {
+    unsigned int default_majority = 0;
     struct hlsl_type *new_type;
 
-    if (!(*modifiers & HLSL_TYPE_MODIFIERS_MASK))
+    /* 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)
+    {
+        if (hlsl_ctx.matrix_majority == HLSL_COLUMN_MAJOR)
+            default_majority = HLSL_MODIFIER_COLUMN_MAJOR;
+        else
+            default_majority = HLSL_MODIFIER_ROW_MAJOR;
+    }
+
+    if (!default_majority && !(*modifiers & HLSL_TYPE_MODIFIERS_MASK))
         return type;
 
-    if (!(new_type = clone_hlsl_type(type)))
+    if (!(new_type = clone_hlsl_type(type, default_majority)))
         return NULL;
 
     new_type->modifiers = add_modifiers(new_type->modifiers, *modifiers, loc);
@@ -738,6 +759,9 @@ static struct list *gen_struct_fields(struct hlsl_type *type, DWORD modifiers, s
     struct hlsl_struct_field *field;
     struct list *list;
 
+    if (type->type == HLSL_CLASS_MATRIX)
+        assert(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
+
     list = d3dcompiler_alloc(sizeof(*list));
     if (!list)
     {
@@ -801,7 +825,7 @@ static BOOL add_typedef(DWORD modifiers, struct hlsl_type *orig_type, struct lis
         if (v->array_size)
             type = new_array_type(orig_type, v->array_size);
         else
-            type = clone_hlsl_type(orig_type);
+            type = clone_hlsl_type(orig_type, 0);
         if (!type)
         {
             ERR("Out of memory\n");
@@ -834,6 +858,9 @@ static BOOL add_func_parameter(struct list *list, struct parse_parameter *param,
 {
     struct hlsl_ir_var *decl = d3dcompiler_alloc(sizeof(*decl));
 
+    if (param->type->type == HLSL_CLASS_MATRIX)
+        assert(param->type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
+
     if (!decl)
     {
         ERR("Out of memory.\n");
@@ -2066,7 +2093,7 @@ postfix_expr:             primary_expr
                                 }
                                 inc = new_unary_expr(HLSL_IR_UNOP_POSTINC, node_from_list($1), loc);
                                 /* Post increment/decrement expressions are considered const */
-                                inc->data_type = clone_hlsl_type(inc->data_type);
+                                inc->data_type = clone_hlsl_type(inc->data_type, 0);
                                 inc->data_type->modifiers |= HLSL_MODIFIER_CONST;
                                 $$ = append_unop($1, inc);
                             }
@@ -2083,7 +2110,7 @@ postfix_expr:             primary_expr
                                 }
                                 inc = new_unary_expr(HLSL_IR_UNOP_POSTDEC, node_from_list($1), loc);
                                 /* Post increment/decrement expressions are considered const */
-                                inc->data_type = clone_hlsl_type(inc->data_type);
+                                inc->data_type = clone_hlsl_type(inc->data_type, 0);
                                 inc->data_type->modifiers |= HLSL_MODIFIER_CONST;
                                 $$ = append_unop($1, inc);
                             }
diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c
index 84323c334f8..ff779891fd8 100644
--- a/dlls/d3dcompiler_43/utils.c
+++ b/dlls/d3dcompiler_43/utils.c
@@ -927,7 +927,7 @@ BOOL compare_hlsl_types(const struct hlsl_type *t1, const struct hlsl_type *t2)
     return TRUE;
 }
 
-struct hlsl_type *clone_hlsl_type(struct hlsl_type *old)
+struct hlsl_type *clone_hlsl_type(struct hlsl_type *old, unsigned int default_majority)
 {
     struct hlsl_type *type;
     struct hlsl_struct_field *old_field, *field;
@@ -952,11 +952,13 @@ struct hlsl_type *clone_hlsl_type(struct hlsl_type *old)
     type->dimx = old->dimx;
     type->dimy = old->dimy;
     type->modifiers = old->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 = old->e.array.type;
+            type->e.array.type = clone_hlsl_type(old->e.array.type, default_majority);
             type->e.array.elements_count = old->e.array.elements_count;
             break;
         case HLSL_CLASS_STRUCT:
@@ -984,7 +986,7 @@ struct hlsl_type *clone_hlsl_type(struct hlsl_type *old)
                     d3dcompiler_free(type);
                     return NULL;
                 }
-                field->type = clone_hlsl_type(old_field->type);
+                field->type = clone_hlsl_type(old_field->type, default_majority);
                 field->name = d3dcompiler_strdup(old_field->name);
                 if (old_field->semantic)
                     field->semantic = d3dcompiler_strdup(old_field->semantic);
-- 
2.26.0




More information about the wine-devel mailing list