[PATCH vkd3d 2/5] vkd3d-shader: Move add_assignment() to hlsl.y.
Zebediah Figura
zfigura at codeweavers.com
Sat Jan 30 13:51:33 CST 2021
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
libs/vkd3d-shader/hlsl.c | 141 ---------------------------------------
libs/vkd3d-shader/hlsl.h | 2 -
libs/vkd3d-shader/hlsl.y | 141 +++++++++++++++++++++++++++++++++++++++
3 files changed, 141 insertions(+), 143 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
index e73ed923..b919a53b 100644
--- a/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d-shader/hlsl.c
@@ -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;
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
index aabfbaf9..6efdfbb7 100644
--- a/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d-shader/hlsl.h
@@ -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,
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index df155a08..15023019 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -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)
{
--
2.30.0
More information about the wine-devel
mailing list