Signed-off-by: Francisco Casas fcasas@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 106 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index bcc9e4d7..a24192a3 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1321,6 +1321,109 @@ static bool add_increment(struct hlsl_ctx *ctx, struct list *instrs, bool decrem return true; }
+static void append_node_components(struct hlsl_ctx *ctx, struct list *instrs, + struct hlsl_ir_node *node, struct hlsl_ir_node **comps, unsigned int *comps_count, + const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *type = node->data_type; + + switch (type->type) + { + case HLSL_CLASS_SCALAR: + { + comps[*comps_count] = node; + *comps_count += 1; + break; + } + case HLSL_CLASS_VECTOR: + { + struct hlsl_type *cast_type = hlsl_get_scalar_type(ctx, type->base_type); + struct hlsl_ir_swizzle *swizzle; + struct hlsl_ir_node *cast; + unsigned int i; + + for (i = 0; i < type->dimx; i++) + { + if (!(swizzle = hlsl_new_swizzle(ctx, hlsl_swizzle_from_writemask(1 << i), 1, node, loc))) + return; + list_add_tail(instrs, &swizzle->node.entry); + + if (!(cast = add_implicit_conversion(ctx, instrs, &swizzle->node, cast_type, loc))) + return; + + comps[*comps_count] = cast; + *comps_count += 1; + } + break; + } + case HLSL_CLASS_MATRIX: + { + hlsl_fixme(ctx, loc, "Flattening of matrices."); + break; + } + case HLSL_CLASS_STRUCT: + { + struct hlsl_struct_field *field; + struct hlsl_ir_load *load; + + LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) + { + if (!(load = add_record_load(ctx, instrs, node, field, *loc))) + return; + + append_node_components(ctx, instrs, &load->node, comps, comps_count, loc); + } + break; + } + case HLSL_CLASS_ARRAY: + { + struct hlsl_ir_constant *c; + struct hlsl_ir_load *load; + unsigned int i; + + for (i = 0; i < type->e.array.elements_count; i++) + { + if (!(c = hlsl_new_uint_constant(ctx, i, *loc))) + return; + list_add_tail(instrs, &c->node.entry); + + if (!(load = add_array_load(ctx, instrs, node, &c->node, *loc))) + return; + + append_node_components(ctx, instrs, &load->node, comps, comps_count, loc); + } + break; + } + case HLSL_CLASS_OBJECT: + { + hlsl_fixme(ctx, loc, "Flattening of objects."); + break; + } + } +} + +static void flatten_parse_initializer(struct hlsl_ctx *ctx, struct parse_initializer *initializer) +{ + unsigned int size = initializer_size(initializer); + unsigned int new_args_count = 0; + struct hlsl_ir_node **new_args; + unsigned int i = 0; + + new_args = hlsl_alloc(ctx, size * sizeof(struct hlsl_ir_node *)); + if (!new_args) + return; + + for (i = 0; i < initializer->args_count; i++) + { + append_node_components(ctx, initializer->instrs, initializer->args[i], new_args, + &new_args_count, &initializer->args[i]->loc); + } + + vkd3d_free(initializer->args); + initializer->args = new_args; + initializer->args_count = new_args_count; +} + static void initialize_numeric_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, struct parse_initializer *initializer, unsigned int reg_offset, struct hlsl_type *type, unsigned int *initializer_offset) @@ -1586,9 +1689,10 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t { unsigned int initializer_offset = 0;
+ flatten_parse_initializer(ctx, &v->initializer); if (v->initializer.args_count != size) { - hlsl_fixme(ctx, &v->loc, "Flatten initializer."); + hlsl_fixme(ctx, &v->loc, "Could not flatten initializer."); free_parse_initializer(&v->initializer); vkd3d_free(v); continue;