vkd3d-shader: Move add_assignment() to hlsl.y.

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Matteo Bruni <mbruni@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2021-01-30 13:51:33 -06:00 committed by Alexandre Julliard
parent 9b2e8fb1db
commit 60cde237c5
3 changed files with 141 additions and 143 deletions

View File

@ -704,147 +704,6 @@ struct hlsl_ir_var *new_synthetic_var(const char *name, struct hlsl_type *type,
return var;
}
static enum hlsl_ir_expr_op op_from_assignment(enum parse_assign_op op)
{
static const enum hlsl_ir_expr_op ops[] =
{
0,
HLSL_IR_BINOP_ADD,
HLSL_IR_BINOP_SUB,
HLSL_IR_BINOP_MUL,
HLSL_IR_BINOP_DIV,
HLSL_IR_BINOP_MOD,
HLSL_IR_BINOP_LSHIFT,
HLSL_IR_BINOP_RSHIFT,
HLSL_IR_BINOP_BIT_AND,
HLSL_IR_BINOP_BIT_OR,
HLSL_IR_BINOP_BIT_XOR,
};
return ops[op];
}
static BOOL invert_swizzle(unsigned int *swizzle, unsigned int *writemask, unsigned int *ret_width)
{
unsigned int i, j, bit = 0, inverted = 0, width, new_writemask = 0, new_swizzle = 0;
/* Apply the writemask to the swizzle to get a new writemask and swizzle. */
for (i = 0; i < 4; ++i)
{
if (*writemask & (1 << i))
{
unsigned int s = (*swizzle >> (i * 2)) & 3;
new_swizzle |= s << (bit++ * 2);
if (new_writemask & (1 << s))
return FALSE;
new_writemask |= 1 << s;
}
}
width = bit;
/* Invert the swizzle. */
bit = 0;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < width; ++j)
{
unsigned int s = (new_swizzle >> (j * 2)) & 3;
if (s == i)
inverted |= j << (bit++ * 2);
}
}
*swizzle = inverted;
*writemask = new_writemask;
*ret_width = width;
return TRUE;
}
struct hlsl_ir_node *add_assignment(struct list *instrs, struct hlsl_ir_node *lhs,
enum parse_assign_op assign_op, struct hlsl_ir_node *rhs)
{
struct hlsl_ir_assignment *assign;
struct hlsl_type *lhs_type;
DWORD writemask = 0;
lhs_type = lhs->data_type;
if (lhs_type->type <= HLSL_CLASS_LAST_NUMERIC)
{
writemask = (1 << lhs_type->dimx) - 1;
if (!(rhs = add_implicit_conversion(instrs, rhs, lhs_type, &rhs->loc)))
return NULL;
}
if (!(assign = vkd3d_malloc(sizeof(*assign))))
return NULL;
while (lhs->type != HLSL_IR_LOAD)
{
struct hlsl_ir_node *lhs_inner;
if (lhs->type == HLSL_IR_EXPR && expr_from_node(lhs)->op == HLSL_IR_UNOP_CAST)
{
FIXME("Cast on the lhs.\n");
vkd3d_free(assign);
return NULL;
}
else if (lhs->type == HLSL_IR_SWIZZLE)
{
struct hlsl_ir_swizzle *swizzle = swizzle_from_node(lhs);
const struct hlsl_type *swizzle_type = swizzle->node.data_type;
unsigned int width;
if (lhs->data_type->type == HLSL_CLASS_MATRIX)
FIXME("Assignments with writemasks and matrices on lhs are not supported yet.\n");
lhs_inner = swizzle->val.node;
hlsl_src_remove(&swizzle->val);
list_remove(&lhs->entry);
list_add_after(&rhs->entry, &lhs->entry);
hlsl_src_from_node(&swizzle->val, rhs);
if (!invert_swizzle(&swizzle->swizzle, &writemask, &width))
{
hlsl_report_message(lhs->loc, HLSL_LEVEL_ERROR, "invalid writemask");
vkd3d_free(assign);
return NULL;
}
assert(swizzle_type->type == HLSL_CLASS_VECTOR);
if (swizzle_type->dimx != width)
swizzle->node.data_type = hlsl_ctx.builtin_types.vector[swizzle_type->base_type][width - 1];
rhs = &swizzle->node;
}
else
{
hlsl_report_message(lhs->loc, HLSL_LEVEL_ERROR, "invalid lvalue");
vkd3d_free(assign);
return NULL;
}
lhs = lhs_inner;
}
init_node(&assign->node, HLSL_IR_ASSIGNMENT, lhs_type, lhs->loc);
assign->writemask = writemask;
assign->lhs.var = load_from_node(lhs)->src.var;
hlsl_src_from_node(&assign->lhs.offset, load_from_node(lhs)->src.offset.node);
if (assign_op != ASSIGN_OP_ASSIGN)
{
enum hlsl_ir_expr_op op = op_from_assignment(assign_op);
struct hlsl_ir_node *expr;
TRACE("Adding an expression for the compound assignment.\n");
expr = new_binary_expr(op, lhs, rhs);
list_add_after(&rhs->entry, &expr->entry);
rhs = expr;
}
hlsl_src_from_node(&assign->rhs, rhs);
list_add_tail(instrs, &assign->node.entry);
return &assign->node;
}
static BOOL type_is_single_reg(const struct hlsl_type *type)
{
return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_VECTOR;

View File

@ -592,8 +592,6 @@ static inline void set_parse_status(enum parse_status *current, enum parse_statu
*current = PARSE_WARN;
}
struct hlsl_ir_node *add_assignment(struct list *instrs, struct hlsl_ir_node *lhs,
enum parse_assign_op assign_op, struct hlsl_ir_node *rhs) DECLSPEC_HIDDEN;
struct hlsl_ir_expr *add_expr(struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[3],
struct source_location *loc) DECLSPEC_HIDDEN;
struct hlsl_ir_node *add_implicit_conversion(struct list *instrs, struct hlsl_ir_node *node, struct hlsl_type *type,

View File

@ -842,6 +842,147 @@ static struct list *add_binary_expr(struct list *list1, struct list *list2,
return list1;
}
static enum hlsl_ir_expr_op op_from_assignment(enum parse_assign_op op)
{
static const enum hlsl_ir_expr_op ops[] =
{
0,
HLSL_IR_BINOP_ADD,
HLSL_IR_BINOP_SUB,
HLSL_IR_BINOP_MUL,
HLSL_IR_BINOP_DIV,
HLSL_IR_BINOP_MOD,
HLSL_IR_BINOP_LSHIFT,
HLSL_IR_BINOP_RSHIFT,
HLSL_IR_BINOP_BIT_AND,
HLSL_IR_BINOP_BIT_OR,
HLSL_IR_BINOP_BIT_XOR,
};
return ops[op];
}
static BOOL invert_swizzle(unsigned int *swizzle, unsigned int *writemask, unsigned int *ret_width)
{
unsigned int i, j, bit = 0, inverted = 0, width, new_writemask = 0, new_swizzle = 0;
/* Apply the writemask to the swizzle to get a new writemask and swizzle. */
for (i = 0; i < 4; ++i)
{
if (*writemask & (1 << i))
{
unsigned int s = (*swizzle >> (i * 2)) & 3;
new_swizzle |= s << (bit++ * 2);
if (new_writemask & (1 << s))
return FALSE;
new_writemask |= 1 << s;
}
}
width = bit;
/* Invert the swizzle. */
bit = 0;
for (i = 0; i < 4; ++i)
{
for (j = 0; j < width; ++j)
{
unsigned int s = (new_swizzle >> (j * 2)) & 3;
if (s == i)
inverted |= j << (bit++ * 2);
}
}
*swizzle = inverted;
*writemask = new_writemask;
*ret_width = width;
return TRUE;
}
static struct hlsl_ir_node *add_assignment(struct list *instrs, struct hlsl_ir_node *lhs,
enum parse_assign_op assign_op, struct hlsl_ir_node *rhs)
{
struct hlsl_ir_assignment *assign;
struct hlsl_type *lhs_type;
DWORD writemask = 0;
lhs_type = lhs->data_type;
if (lhs_type->type <= HLSL_CLASS_LAST_NUMERIC)
{
writemask = (1 << lhs_type->dimx) - 1;
if (!(rhs = add_implicit_conversion(instrs, rhs, lhs_type, &rhs->loc)))
return NULL;
}
if (!(assign = vkd3d_malloc(sizeof(*assign))))
return NULL;
while (lhs->type != HLSL_IR_LOAD)
{
struct hlsl_ir_node *lhs_inner;
if (lhs->type == HLSL_IR_EXPR && expr_from_node(lhs)->op == HLSL_IR_UNOP_CAST)
{
FIXME("Cast on the lhs.\n");
vkd3d_free(assign);
return NULL;
}
else if (lhs->type == HLSL_IR_SWIZZLE)
{
struct hlsl_ir_swizzle *swizzle = swizzle_from_node(lhs);
const struct hlsl_type *swizzle_type = swizzle->node.data_type;
unsigned int width;
if (lhs->data_type->type == HLSL_CLASS_MATRIX)
FIXME("Assignments with writemasks and matrices on lhs are not supported yet.\n");
lhs_inner = swizzle->val.node;
hlsl_src_remove(&swizzle->val);
list_remove(&lhs->entry);
list_add_after(&rhs->entry, &lhs->entry);
hlsl_src_from_node(&swizzle->val, rhs);
if (!invert_swizzle(&swizzle->swizzle, &writemask, &width))
{
hlsl_report_message(lhs->loc, HLSL_LEVEL_ERROR, "invalid writemask");
vkd3d_free(assign);
return NULL;
}
assert(swizzle_type->type == HLSL_CLASS_VECTOR);
if (swizzle_type->dimx != width)
swizzle->node.data_type = hlsl_ctx.builtin_types.vector[swizzle_type->base_type][width - 1];
rhs = &swizzle->node;
}
else
{
hlsl_report_message(lhs->loc, HLSL_LEVEL_ERROR, "invalid lvalue");
vkd3d_free(assign);
return NULL;
}
lhs = lhs_inner;
}
init_node(&assign->node, HLSL_IR_ASSIGNMENT, lhs_type, lhs->loc);
assign->writemask = writemask;
assign->lhs.var = load_from_node(lhs)->src.var;
hlsl_src_from_node(&assign->lhs.offset, load_from_node(lhs)->src.offset.node);
if (assign_op != ASSIGN_OP_ASSIGN)
{
enum hlsl_ir_expr_op op = op_from_assignment(assign_op);
struct hlsl_ir_node *expr;
TRACE("Adding an expression for the compound assignment.\n");
expr = new_binary_expr(op, lhs, rhs);
list_add_after(&rhs->entry, &expr->entry);
rhs = expr;
}
hlsl_src_from_node(&assign->rhs, rhs);
list_add_tail(instrs, &assign->node.entry);
return &assign->node;
}
static void struct_var_initializer(struct list *list, struct hlsl_ir_var *var,
struct parse_initializer *initializer)
{