d3dcompiler: Handle simple struct initializers.

This commit is contained in:
Matteo Bruni 2012-09-26 19:22:35 +02:00 committed by Alexandre Julliard
parent 9cbd80bda1
commit 16360a4f18
3 changed files with 74 additions and 2 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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[] =