Signed-off-by: Zebediah Figura zfigura@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);