Signed-off-by: Zebediah Figura zfigura@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) {