[PATCH vkd3d v2 4/6] vkd3d-shader/hlsl: Flatten initializers.

Francisco Casas fcasas at codeweavers.com
Tue Feb 22 16:13:40 CST 2022


Signed-off-by: Francisco Casas <fcasas at codeweavers.com>
Signed-off-by: Giovanni Mascellani <gmascellani at codeweavers.com>

---
v2:
- formatting.
- flatten_parse_initializer() now returns bool.

Signed-off-by: Francisco Casas <fcasas at codeweavers.com>
---
 libs/vkd3d-shader/hlsl.y | 122 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 119 insertions(+), 3 deletions(-)

diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index 725cbad3..0e882834 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -1321,6 +1321,122 @@ static bool add_increment(struct hlsl_ctx *ctx, struct list *instrs, bool decrem
     return true;
 }
 
+static bool 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 false;
+                list_add_tail(instrs, &swizzle->node.entry);
+
+                if (!(cast = add_implicit_conversion(ctx, instrs, &swizzle->node, cast_type, loc)))
+                    return false;
+
+                comps[*comps_count] = cast;
+                *comps_count += 1;
+            }
+            break;
+        }
+
+        case HLSL_CLASS_MATRIX:
+        {
+            hlsl_fixme(ctx, loc, "Flattening of matrices.");
+            return false;
+        }
+
+        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 false;
+
+                if (!append_node_components(ctx, instrs, &load->node, comps, comps_count, loc))
+                    return false;
+            }
+            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 false;
+                list_add_tail(instrs, &c->node.entry);
+
+                if (!(load = add_array_load(ctx, instrs, node, &c->node, *loc)))
+                    return false;
+
+                if (!append_node_components(ctx, instrs, &load->node, comps, comps_count, loc))
+                    return false;
+            }
+            break;
+        }
+
+        case HLSL_CLASS_OBJECT:
+        {
+            hlsl_fixme(ctx, loc, "Flattening of objects.");
+            return false;
+        }
+    }
+
+    return true;
+}
+
+static bool 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;
+    bool success = true;
+    unsigned int i = 0;
+
+    new_args = hlsl_alloc(ctx, size * sizeof(struct hlsl_ir_node *));
+    if (!new_args)
+        return false;
+
+    for (i = 0; i < initializer->args_count; i++)
+    {
+        success = append_node_components(ctx, initializer->instrs, initializer->args[i], new_args,
+                &new_args_count, &initializer->args[i]->loc);
+        if (!success)
+            break;
+    }
+
+    vkd3d_free(initializer->args);
+    initializer->args = new_args;
+    initializer->args_count = new_args_count;
+    return success;
+}
+
 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)
@@ -1583,14 +1699,14 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t
             {
                 unsigned int initializer_offset = 0;
 
-                if (v->initializer.args_count != size)
+                if (!flatten_parse_initializer(ctx, &v->initializer))
                 {
-                    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;
                 }
-
+                assert(v->initializer.args_count == size);
                 initialize_numeric_var(ctx, var, &v->initializer, 0, type, &initializer_offset);
             }
             else
-- 
2.25.1




More information about the wine-devel mailing list