[PATCH 5/5] d3dcompiler: Handle simple struct initializers.

Matteo Bruni mbruni at codeweavers.com
Wed Sep 26 12:22:35 CDT 2012


---
 dlls/d3dcompiler_43/d3dcompiler_private.h |    1 +
 dlls/d3dcompiler_43/hlsl.y                |   58 ++++++++++++++++++++++++++++-
 dlls/d3dcompiler_43/utils.c               |   17 ++++++++
 3 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h
index 5ed0bda..de948fa 100644
--- a/dlls/d3dcompiler_43/d3dcompiler_private.h
+++ b/dlls/d3dcompiler_43/d3dcompiler_private.h
@@ -1122,6 +1122,7 @@ struct hlsl_ir_expr *hlsl_eq(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
 struct hlsl_ir_expr *hlsl_ne(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
         struct source_location *loc) DECLSPEC_HIDDEN;
 struct hlsl_ir_deref *new_var_deref(struct hlsl_ir_var *var) DECLSPEC_HIDDEN;
+struct hlsl_ir_deref *new_record_deref(struct hlsl_ir_node *record, struct hlsl_struct_field *field) DECLSPEC_HIDDEN;
 struct hlsl_ir_node *make_assignment(struct hlsl_ir_node *left, enum parse_assign_op assign_op,
         DWORD writemask, struct hlsl_ir_node *right) DECLSPEC_HIDDEN;
 void push_scope(struct hlsl_parse_ctx *ctx) DECLSPEC_HIDDEN;
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y
index d8c0d2b..f9a685a 100644
--- a/dlls/d3dcompiler_43/hlsl.y
+++ b/dlls/d3dcompiler_43/hlsl.y
@@ -502,6 +502,61 @@ static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const cha
     return NULL;
 }
 
+static void struct_var_initializer(struct list *list, struct hlsl_ir_var *var, struct list *initializer)
+{
+    struct hlsl_type *type = var->node.data_type;
+    struct hlsl_ir_node *node;
+    struct hlsl_struct_field *field;
+    struct list *cur_node;
+    struct hlsl_ir_node *assignment;
+    struct hlsl_ir_deref *deref;
+
+    if (initializer_size(initializer) != components_count_type(type))
+    {
+        hlsl_report_message(var->node.loc.file, var->node.loc.line, var->node.loc.col, HLSL_LEVEL_ERROR,
+                "structure initializer mismatch");
+        free_instr_list(initializer);
+        return;
+    }
+    cur_node = list_head(initializer);
+    assert(cur_node);
+    node = LIST_ENTRY(cur_node, struct hlsl_ir_node, entry);
+    LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
+    {
+        if (!cur_node)
+        {
+            d3dcompiler_free(initializer);
+            return;
+        }
+        if (components_count_type(field->type) == components_count_type(node->data_type))
+        {
+            deref = new_record_deref(&var->node, field);
+            if (!deref)
+            {
+                ERR("Out of memory.\n");
+                break;
+            }
+            deref->node.loc = node->loc;
+            assignment = make_assignment(&deref->node, ASSIGN_OP_ASSIGN, BWRITERSP_WRITEMASK_ALL, node);
+            list_add_tail(list, &assignment->entry);
+        }
+        else
+            FIXME("Initializing with \"mismatched\" fields is not supported yet.\n");
+        cur_node = list_next(initializer, cur_node);
+        node = LIST_ENTRY(cur_node, struct hlsl_ir_node, entry);
+    }
+
+    /* Free initializer elements in excess. */
+    while (cur_node)
+    {
+        struct list *next = list_next(initializer, cur_node);
+        free_instr(node);
+        cur_node = next;
+        node = LIST_ENTRY(cur_node, struct hlsl_ir_node, entry);
+    }
+    d3dcompiler_free(initializer);
+}
+
 static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, struct list *var_list)
 {
     struct hlsl_type *type;
@@ -599,8 +654,7 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers,
 
             if (type->type == HLSL_CLASS_STRUCT)
             {
-                FIXME("Struct var with an initializer.\n");
-                free_instr_list(v->initializer);
+                struct_var_initializer(statements_list, var, v->initializer);
                 d3dcompiler_free(v);
                 continue;
             }
diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c
index b957643..9f91579 100644
--- a/dlls/d3dcompiler_43/utils.c
+++ b/dlls/d3dcompiler_43/utils.c
@@ -1556,6 +1556,23 @@ struct hlsl_ir_deref *new_var_deref(struct hlsl_ir_var *var)
     return deref;
 }
 
+struct hlsl_ir_deref *new_record_deref(struct hlsl_ir_node *record, struct hlsl_struct_field *field)
+{
+    struct hlsl_ir_deref *deref = d3dcompiler_alloc(sizeof(*deref));
+
+    if (!deref)
+    {
+        ERR("Out of memory.\n");
+        return NULL;
+    }
+    deref->node.type = HLSL_IR_DEREF;
+    deref->node.data_type = field->type;
+    deref->type = HLSL_IR_DEREF_RECORD;
+    deref->v.record.record = record;
+    deref->v.record.field = field;
+    return deref;
+}
+
 static enum hlsl_ir_expr_op op_from_assignment(enum parse_assign_op op)
 {
     static const enum hlsl_ir_expr_op ops[] =
-- 
1.7.8.6




More information about the wine-patches mailing list