d3dcompiler: Parse casts.
This commit is contained in:
parent
46e368934e
commit
ca701b7d69
|
@ -1080,8 +1080,11 @@ struct hlsl_type *clone_hlsl_type(struct hlsl_type *old) DECLSPEC_HIDDEN;
|
|||
struct hlsl_type *get_type(struct hlsl_scope *scope, const char *name, BOOL recursive) DECLSPEC_HIDDEN;
|
||||
BOOL find_function(const char *name) DECLSPEC_HIDDEN;
|
||||
unsigned int components_count_type(struct hlsl_type *type) DECLSPEC_HIDDEN;
|
||||
BOOL compatible_data_types(struct hlsl_type *s1, struct hlsl_type *s2) DECLSPEC_HIDDEN;
|
||||
struct hlsl_ir_expr *new_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node **operands,
|
||||
struct source_location *loc) DECLSPEC_HIDDEN;
|
||||
struct hlsl_ir_expr *new_cast(struct hlsl_ir_node *node, struct hlsl_type *type,
|
||||
struct source_location *loc) DECLSPEC_HIDDEN;
|
||||
struct hlsl_ir_expr *hlsl_mul(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
|
||||
struct source_location *loc) DECLSPEC_HIDDEN;
|
||||
struct hlsl_ir_expr *hlsl_div(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
|
||||
|
|
|
@ -1472,6 +1472,35 @@ unary_expr: postfix_expr
|
|||
$$ = &new_expr(ops[$1], operands, &loc)->node;
|
||||
}
|
||||
}
|
||||
/* var_modifiers just to avoid shift/reduce conflicts */
|
||||
| '(' var_modifiers type array ')' unary_expr
|
||||
{
|
||||
struct hlsl_ir_expr *expr;
|
||||
struct hlsl_type *src_type = $6->data_type;
|
||||
struct hlsl_type *dst_type;
|
||||
struct source_location loc;
|
||||
|
||||
set_location(&loc, &@3);
|
||||
if ($2)
|
||||
{
|
||||
hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
|
||||
"unexpected modifier in a cast");
|
||||
return 1;
|
||||
}
|
||||
|
||||
dst_type = $3;
|
||||
|
||||
if (!compatible_data_types(src_type, dst_type))
|
||||
{
|
||||
hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
|
||||
"can't cast from %s to %s",
|
||||
debug_hlsl_type(src_type), debug_hlsl_type(dst_type));
|
||||
return 1;
|
||||
}
|
||||
|
||||
expr = new_cast($6, dst_type, &loc);
|
||||
$$ = expr ? &expr->node : NULL;
|
||||
}
|
||||
|
||||
unary_op: '+'
|
||||
{
|
||||
|
|
|
@ -1031,6 +1031,60 @@ static BOOL convertible_data_type(struct hlsl_type *type)
|
|||
return type->type != HLSL_CLASS_OBJECT;
|
||||
}
|
||||
|
||||
BOOL compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2)
|
||||
{
|
||||
if (!convertible_data_type(t1) || !convertible_data_type(t2))
|
||||
return FALSE;
|
||||
|
||||
if (t1->type <= HLSL_CLASS_LAST_NUMERIC)
|
||||
{
|
||||
/* Scalar vars can be cast to pretty much everything */
|
||||
if (t1->dimx == 1 && t1->dimy == 1)
|
||||
return TRUE;
|
||||
|
||||
if (t1->type == HLSL_CLASS_VECTOR && t2->type == HLSL_CLASS_VECTOR)
|
||||
return t1->dimx >= t2->dimx;
|
||||
}
|
||||
|
||||
/* The other way around is true too i.e. whatever to scalar */
|
||||
if (t2->type <= HLSL_CLASS_LAST_NUMERIC && t2->dimx == 1 && t2->dimy == 1)
|
||||
return TRUE;
|
||||
|
||||
if (t1->type == HLSL_CLASS_ARRAY)
|
||||
{
|
||||
if (compare_hlsl_types(t1->e.array.type, t2))
|
||||
/* e.g. float4[3] to float4 is allowed */
|
||||
return TRUE;
|
||||
|
||||
if (t2->type == HLSL_CLASS_ARRAY || t2->type == HLSL_CLASS_STRUCT)
|
||||
return components_count_type(t1) >= components_count_type(t2);
|
||||
else
|
||||
return components_count_type(t1) == components_count_type(t2);
|
||||
}
|
||||
|
||||
if (t1->type == HLSL_CLASS_STRUCT)
|
||||
return components_count_type(t1) >= components_count_type(t2);
|
||||
|
||||
if (t2->type == HLSL_CLASS_ARRAY || t2->type == HLSL_CLASS_STRUCT)
|
||||
return components_count_type(t1) == components_count_type(t2);
|
||||
|
||||
if (t1->type == HLSL_CLASS_MATRIX || t2->type == HLSL_CLASS_MATRIX)
|
||||
{
|
||||
if (t1->type == HLSL_CLASS_MATRIX && t2->type == HLSL_CLASS_MATRIX && t1->dimx >= t2->dimx && t1->dimy >= t2->dimy)
|
||||
return TRUE;
|
||||
|
||||
/* Matrix-vector conversion is apparently allowed if they have the same components count */
|
||||
if ((t1->type == HLSL_CLASS_VECTOR || t2->type == HLSL_CLASS_VECTOR)
|
||||
&& components_count_type(t1) == components_count_type(t2))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (components_count_type(t1) >= components_count_type(t2))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL implicit_compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2)
|
||||
{
|
||||
if (!convertible_data_type(t1) || !convertible_data_type(t2))
|
||||
|
@ -1322,6 +1376,20 @@ struct hlsl_ir_expr *new_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node **ope
|
|||
return expr;
|
||||
}
|
||||
|
||||
struct hlsl_ir_expr *new_cast(struct hlsl_ir_node *node, struct hlsl_type *type,
|
||||
struct source_location *loc)
|
||||
{
|
||||
struct hlsl_ir_expr *cast;
|
||||
struct hlsl_ir_node *operands[3];
|
||||
|
||||
operands[0] = node;
|
||||
operands[1] = operands[2] = NULL;
|
||||
cast = new_expr(HLSL_IR_UNOP_CAST, operands, loc);
|
||||
if (cast)
|
||||
cast->node.data_type = type;
|
||||
return cast;
|
||||
}
|
||||
|
||||
struct hlsl_ir_expr *hlsl_mul(struct hlsl_ir_node *op1, struct hlsl_ir_node *op2,
|
||||
struct source_location *loc)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue