diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index e8456694..5e85fa2f 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -242,6 +242,18 @@ static void replace_and_remove_node(struct hlsl_ir_node *old, struct hlsl_ir_nod hlsl_free_instr(old); } +/* Replace an instruction with a swizzle instruction. */ +static void replace_swizzle(struct hlsl_ir_node *old, struct hlsl_ir_swizzle *swizzle) +{ + struct hlsl_ir_node *val_instr = swizzle->val.node; + + /* If old is the argument of swizzle, simply doing replace_node() would + * make swizzle have itself as argument. */ + hlsl_src_remove(&swizzle->val); + replace_node(old, &swizzle->node); + hlsl_src_from_node(&swizzle->val, val_instr); +} + /* Lower casts from vec1 to vecN to swizzles. */ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { @@ -267,9 +279,7 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, v list_add_after(&cast->node.entry, &swizzle->node.entry); cast->node.data_type = hlsl_get_scalar_type(ctx, dst_type->base_type); - replace_node(&cast->node, &swizzle->node); - hlsl_src_remove(&swizzle->val); - hlsl_src_from_node(&swizzle->val, &cast->node); + replace_swizzle(&cast->node, swizzle); return true; }