d3dcompiler: Handle simple struct initializers.
This commit is contained in:
parent
9cbd80bda1
commit
16360a4f18
|
@ -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 hlsl_ir_expr *hlsl_ne(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
|
||||||
struct source_location *loc) DECLSPEC_HIDDEN;
|
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_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,
|
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;
|
DWORD writemask, struct hlsl_ir_node *right) DECLSPEC_HIDDEN;
|
||||||
void push_scope(struct hlsl_parse_ctx *ctx) DECLSPEC_HIDDEN;
|
void push_scope(struct hlsl_parse_ctx *ctx) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -502,6 +502,61 @@ static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const cha
|
||||||
return NULL;
|
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)
|
static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers, struct list *var_list)
|
||||||
{
|
{
|
||||||
struct hlsl_type *type;
|
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)
|
if (type->type == HLSL_CLASS_STRUCT)
|
||||||
{
|
{
|
||||||
FIXME("Struct var with an initializer.\n");
|
struct_var_initializer(statements_list, var, v->initializer);
|
||||||
free_instr_list(v->initializer);
|
|
||||||
d3dcompiler_free(v);
|
d3dcompiler_free(v);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1556,6 +1556,23 @@ struct hlsl_ir_deref *new_var_deref(struct hlsl_ir_var *var)
|
||||||
return deref;
|
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 enum hlsl_ir_expr_op op_from_assignment(enum parse_assign_op op)
|
||||||
{
|
{
|
||||||
static const enum hlsl_ir_expr_op ops[] =
|
static const enum hlsl_ir_expr_op ops[] =
|
||||||
|
|
Loading…
Reference in New Issue