[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