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;
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- I think usually it is preferred to leave blank lines between case statements.
Also, right now you check for flatten_parse_initializer() succeeding by seeing if after the call the initializer has the right number of components. I'd rather return a success value from flatten_parse_initializer() and assume that if it returns true, then it has the right number of components.
The philosophy is that ideally error reporting should be as close to where the error was first noticed as possible.
Thanks, Giovanni.
Il 15/02/22 21:17, Francisco Casas ha scritto:
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;