Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/d3dcompiler_43/utils.c | 31 +++++++++++++++++++++++--------
1 file changed, 23 insertions(+), 8 deletions(-)
diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c
index 60bb5ff8145..7093e9eb2c0 100644
--- a/dlls/d3dcompiler_43/utils.c
+++ b/dlls/d3dcompiler_43/utils.c
@@ -1403,29 +1403,29 @@ static enum hlsl_ir_expr_op op_from_assignment(enum parse_assign_op op)
return ops[op];
}
-static unsigned int invert_swizzle(unsigned int *swizzle, unsigned int writemask)
+static BOOL invert_swizzle(unsigned int *swizzle, unsigned int *writemask, unsigned int *ret_width)
{
- unsigned int i, j, bit = 0, inverted = 0, components, new_writemask = 0, new_swizzle = 0;
+ 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))
+ if (*writemask & (1 << i))
{
unsigned int s = (*swizzle >> (i * 2)) & 3;
new_swizzle |= s << (bit++ * 2);
if (new_writemask & (1 << s))
- return 0;
+ return FALSE;
new_writemask |= 1 << s;
}
}
- components = bit;
+ width = bit;
/* Invert the swizzle. */
bit = 0;
for (i = 0; i < 4; ++i)
{
- for (j = 0; j < components; ++j)
+ for (j = 0; j < width; ++j)
{
unsigned int s = (new_swizzle >> (j * 2)) & 3;
if (s == i)
@@ -1434,7 +1434,9 @@ static unsigned int invert_swizzle(unsigned int *swizzle, unsigned int writemask
}
*swizzle = inverted;
- return new_writemask;
+ *writemask = new_writemask;
+ *ret_width = width;
+ return TRUE;
}
struct hlsl_ir_node *make_assignment(struct hlsl_ir_node *lhs, enum parse_assign_op assign_op,
@@ -1463,6 +1465,8 @@ struct hlsl_ir_node *make_assignment(struct hlsl_ir_node *lhs, enum parse_assign
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");
@@ -1472,12 +1476,23 @@ struct hlsl_ir_node *make_assignment(struct hlsl_ir_node *lhs, enum parse_assign
list_add_after(&rhs->entry, &lhs->entry);
swizzle->val = rhs;
- if (!(writemask = invert_swizzle(&swizzle->swizzle, writemask)))
+ if (!invert_swizzle(&swizzle->swizzle, &writemask, &width))
{
hlsl_report_message(lhs->loc, HLSL_LEVEL_ERROR, "invalid writemask");
d3dcompiler_free(assign);
return NULL;
}
+ assert(swizzle_type->type == HLSL_CLASS_VECTOR);
+ if (swizzle_type->dimx != width)
+ {
+ struct hlsl_type *type;
+ if (!(type = new_hlsl_type(NULL, HLSL_CLASS_VECTOR, swizzle_type->base_type, width, 1)))
+ {
+ d3dcompiler_free(assign);
+ return NULL;
+ }
+ swizzle->node.data_type = type;
+ }
rhs = &swizzle->node;
}
else
--
2.26.2