Zebediah Figura : vkd3d-shader: Build fused assignment operations before unwrapping swizzles from the LHS.

Alexandre Julliard julliard at winehq.org
Mon Mar 15 16:58:42 CDT 2021


Module: vkd3d
Branch: master
Commit: 1aca2016510526fcaf9b248de7f07d93a8971686
URL:    https://source.winehq.org/git/vkd3d.git/?a=commit;h=1aca2016510526fcaf9b248de7f07d93a8971686

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Tue Mar  9 19:42:49 2021 -0600

vkd3d-shader: Build fused assignment operations before unwrapping swizzles from the LHS.

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 libs/vkd3d-shader/hlsl.y | 54 ++++++++++++++++++++++--------------------------
 1 file changed, 25 insertions(+), 29 deletions(-)

diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index 815aac9..6fceafb 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -1259,12 +1259,22 @@ static bool invert_swizzle(unsigned int *swizzle, unsigned int *writemask, unsig
 static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *lhs,
         enum parse_assign_op assign_op, struct hlsl_ir_node *rhs)
 {
+    struct hlsl_type *lhs_type = lhs->data_type;
     struct hlsl_ir_assignment *assign;
-    struct hlsl_type *lhs_type;
     struct hlsl_ir_expr *copy;
     DWORD writemask = 0;
 
-    lhs_type = lhs->data_type;
+    if (assign_op != ASSIGN_OP_ASSIGN)
+    {
+        enum hlsl_ir_expr_op op = op_from_assignment(assign_op);
+        struct hlsl_ir_node *args[3] = {lhs, rhs};
+        struct hlsl_ir_expr *expr;
+
+        if (!(expr = add_expr(ctx, instrs, op, args, &rhs->loc)))
+            return NULL;
+        rhs = &expr->node;
+    }
+
     if (lhs_type->type <= HLSL_CLASS_LAST_NUMERIC)
     {
         writemask = (1 << lhs_type->dimx) - 1;
@@ -1278,8 +1288,6 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
 
     while (lhs->type != HLSL_IR_LOAD)
     {
-        struct hlsl_ir_node *lhs_inner;
-
         if (lhs->type == HLSL_IR_EXPR && hlsl_ir_expr(lhs)->op == HLSL_IR_UNOP_CAST)
         {
             FIXME("Cast on the lhs.\n");
@@ -1288,29 +1296,28 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
         }
         else if (lhs->type == HLSL_IR_SWIZZLE)
         {
-            struct hlsl_ir_swizzle *swizzle = hlsl_ir_swizzle(lhs);
-            const struct hlsl_type *swizzle_type = swizzle->node.data_type;
-            unsigned int width;
+            struct hlsl_ir_swizzle *swizzle = hlsl_ir_swizzle(lhs), *new_swizzle;
+            unsigned int width, s = swizzle->swizzle;
 
             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))
+            if (!invert_swizzle(&s, &writemask, &width))
             {
                 hlsl_error(ctx, lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_WRITEMASK, "Invalid writemask.");
                 vkd3d_free(assign);
                 return NULL;
             }
-            assert(swizzle_type->type == HLSL_CLASS_VECTOR);
-            if (swizzle_type->dimx != width)
-                swizzle->node.data_type = ctx->builtin_types.vector[swizzle_type->base_type][width - 1];
-            rhs = &swizzle->node;
+
+            if (!(new_swizzle = hlsl_new_swizzle(ctx, s, width, rhs, &swizzle->node.loc)))
+            {
+                vkd3d_free(assign);
+                return NULL;
+            }
+            list_add_tail(instrs, &new_swizzle->node.entry);
+
+            lhs = swizzle->val.node;
+            rhs = &new_swizzle->node;
         }
         else
         {
@@ -1318,23 +1325,12 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
             vkd3d_free(assign);
             return NULL;
         }
-
-        lhs = lhs_inner;
     }
 
     init_node(&assign->node, HLSL_IR_ASSIGNMENT, NULL, lhs->loc);
     assign->writemask = writemask;
     assign->lhs.var = hlsl_ir_load(lhs)->src.var;
     hlsl_src_from_node(&assign->lhs.offset, hlsl_ir_load(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;
-
-        expr = hlsl_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);
 




More information about the wine-cvs mailing list