From: Zebediah Figura Subject: [PATCH 1/5] d3dcompiler: Emit constructors as sequences of stores to a synthetic variable. Message-Id: <20200605221933.1861389-1-zfigura@codeweavers.com> Date: Fri, 5 Jun 2020 17:19:29 -0500 Signed-off-by: Zebediah Figura --- dlls/d3dcompiler_43/d3dcompiler_private.h | 14 ---- dlls/d3dcompiler_43/hlsl.y | 94 +++++++++++++---------- dlls/d3dcompiler_43/utils.c | 25 ------ 3 files changed, 52 insertions(+), 81 deletions(-) diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h index a61b84d6b54..c9bb6ced6c7 100644 --- a/dlls/d3dcompiler_43/d3dcompiler_private.h +++ b/dlls/d3dcompiler_43/d3dcompiler_private.h @@ -648,7 +648,6 @@ enum hlsl_ir_node_type { HLSL_IR_ASSIGNMENT = 0, HLSL_IR_CONSTANT, - HLSL_IR_CONSTRUCTOR, HLSL_IR_EXPR, HLSL_IR_IF, HLSL_IR_LOAD, @@ -880,13 +879,6 @@ struct hlsl_ir_constant } v; }; -struct hlsl_ir_constructor -{ - struct hlsl_ir_node node; - struct hlsl_ir_node *args[16]; - unsigned int args_count; -}; - struct hlsl_scope { struct list entry; @@ -1042,12 +1034,6 @@ static inline struct hlsl_ir_swizzle *swizzle_from_node(const struct hlsl_ir_nod return CONTAINING_RECORD(node, struct hlsl_ir_swizzle, node); } -static inline struct hlsl_ir_constructor *constructor_from_node(const struct hlsl_ir_node *node) -{ - assert(node->type == HLSL_IR_CONSTRUCTOR); - return CONTAINING_RECORD(node, struct hlsl_ir_constructor, node); -} - static inline struct hlsl_ir_if *if_from_node(const struct hlsl_ir_node *node) { assert(node->type == HLSL_IR_IF); diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y index 436b731fd16..8fbb879778d 100644 --- a/dlls/d3dcompiler_43/hlsl.y +++ b/dlls/d3dcompiler_43/hlsl.y @@ -1244,7 +1244,6 @@ static unsigned int evaluate_array_dimension(struct hlsl_ir_node *node) return 0; } } - case HLSL_IR_CONSTRUCTOR: case HLSL_IR_EXPR: case HLSL_IR_LOAD: case HLSL_IR_SWIZZLE: @@ -2415,41 +2414,60 @@ postfix_expr: primary_expr } $$ = append_binop($1, $3, &load->node); } - /* "var_modifiers" doesn't make sense in this case, but it's needed - in the grammar to avoid shift/reduce conflicts. */ - | var_modifiers type '(' initializer_expr_list ')' - { - struct hlsl_ir_constructor *constructor; - TRACE("%s constructor.\n", debug_hlsl_type($2)); - if ($1) - { - hlsl_report_message(get_location(&@1), HLSL_LEVEL_ERROR, - "unexpected modifier on a constructor\n"); - YYABORT; - } - if ($2->type > HLSL_CLASS_LAST_NUMERIC) - { - hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR, - "constructors may only be used with numeric data types\n"); - YYABORT; - } - if ($2->dimx * $2->dimy != initializer_size(&$4)) - { - hlsl_report_message(get_location(&@4), HLSL_LEVEL_ERROR, - "expected %u components in constructor, but got %u\n", - $2->dimx * $2->dimy, initializer_size(&$4)); - YYABORT; - } - assert($4.args_count <= ARRAY_SIZE(constructor->args)); + /* "var_modifiers" doesn't make sense in this case, but it's needed + in the grammar to avoid shift/reduce conflicts. */ + | var_modifiers type '(' initializer_expr_list ')' + { + struct hlsl_ir_assignment *assignment; + unsigned int i, writemask_offset = 0; + static unsigned int counter; + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + char name[23]; - constructor = d3dcompiler_alloc(sizeof(*constructor)); - init_node(&constructor->node, HLSL_IR_CONSTRUCTOR, $2, get_location(&@3)); - constructor->args_count = $4.args_count; - memcpy(constructor->args, $4.args, $4.args_count * sizeof(*$4.args)); - d3dcompiler_free($4.args); - $$ = append_unop($4.instrs, &constructor->node); - } + if ($1) + { + hlsl_report_message(get_location(&@1), HLSL_LEVEL_ERROR, + "unexpected modifier on a constructor\n"); + YYABORT; + } + if ($2->type > HLSL_CLASS_LAST_NUMERIC) + { + hlsl_report_message(get_location(&@2), HLSL_LEVEL_ERROR, + "constructors may only be used with numeric data types\n"); + YYABORT; + } + if ($2->dimx * $2->dimy != initializer_size(&$4)) + { + hlsl_report_message(get_location(&@4), HLSL_LEVEL_ERROR, + "expected %u components in constructor, but got %u\n", + $2->dimx * $2->dimy, initializer_size(&$4)); + YYABORT; + } + + if ($2->type == HLSL_CLASS_MATRIX) + FIXME("Matrix constructors are not supported yet.\n"); + + sprintf(name, "", counter++); + if (!(var = new_synthetic_var(name, $2, get_location(&@2)))) + YYABORT; + for (i = 0; i < $4.args_count; ++i) + { + const struct hlsl_type *arg_type = $4.args[i]->data_type; + unsigned int component_count = arg_type->dimx * arg_type->dimy; + + if (!(assignment = new_assignment(var, NULL, $4.args[i], + ((1 << component_count) - 1) << writemask_offset, $4.args[i]->loc))) + YYABORT; + writemask_offset += component_count; + list_add_tail($4.instrs, &assignment->node.entry); + } + d3dcompiler_free($4.args); + if (!(load = new_var_load(var, get_location(&@2)))) + YYABORT; + $$ = append_unop($4.instrs, &load->node); + } unary_expr: postfix_expr { @@ -2834,14 +2852,6 @@ static void compute_liveness_recurse(struct list *instrs, unsigned int loop_firs assignment->lhs.offset->last_read = instr->index; break; } - case HLSL_IR_CONSTRUCTOR: - { - struct hlsl_ir_constructor *constructor = constructor_from_node(instr); - unsigned int i; - for (i = 0; i < constructor->args_count; ++i) - constructor->args[i]->last_read = instr->index; - break; - } case HLSL_IR_EXPR: { struct hlsl_ir_expr *expr = expr_from_node(instr); diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c index ec0da2d4034..4f156b678f2 100644 --- a/dlls/d3dcompiler_43/utils.c +++ b/dlls/d3dcompiler_43/utils.c @@ -1763,7 +1763,6 @@ const char *debug_node_type(enum hlsl_ir_node_type type) { "HLSL_IR_ASSIGNMENT", "HLSL_IR_CONSTANT", - "HLSL_IR_CONSTRUCTOR", "HLSL_IR_EXPR", "HLSL_IR_IF", "HLSL_IR_LOAD", @@ -1951,19 +1950,6 @@ static void debug_dump_ir_expr(const struct hlsl_ir_expr *expr) wine_dbg_printf(")"); } -static void debug_dump_ir_constructor(const struct hlsl_ir_constructor *constructor) -{ - unsigned int i; - - wine_dbg_printf("%s (", debug_hlsl_type(constructor->node.data_type)); - for (i = 0; i < constructor->args_count; ++i) - { - debug_dump_src(constructor->args[i]); - wine_dbg_printf(" "); - } - wine_dbg_printf(")"); -} - static const char *debug_writemask(DWORD writemask) { static const char components[] = {'x', 'y', 'z', 'w'}; @@ -2078,9 +2064,6 @@ static void debug_dump_instr(const struct hlsl_ir_node *instr) case HLSL_IR_SWIZZLE: debug_dump_ir_swizzle(swizzle_from_node(instr)); break; - case HLSL_IR_CONSTRUCTOR: - debug_dump_ir_constructor(constructor_from_node(instr)); - break; case HLSL_IR_JUMP: debug_dump_ir_jump(jump_from_node(instr)); break; @@ -2175,11 +2158,6 @@ static void free_ir_swizzle(struct hlsl_ir_swizzle *swizzle) d3dcompiler_free(swizzle); } -static void free_ir_constructor(struct hlsl_ir_constructor *constructor) -{ - d3dcompiler_free(constructor); -} - static void free_ir_expr(struct hlsl_ir_expr *expr) { d3dcompiler_free(expr); @@ -2221,9 +2199,6 @@ void free_instr(struct hlsl_ir_node *node) case HLSL_IR_SWIZZLE: free_ir_swizzle(swizzle_from_node(node)); break; - case HLSL_IR_CONSTRUCTOR: - free_ir_constructor(constructor_from_node(node)); - break; case HLSL_IR_EXPR: free_ir_expr(expr_from_node(node)); break; -- 2.26.2