diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index c70ab658..84da2fcb 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -4007,8 +4007,8 @@ void hlsl_add_function(struct hlsl_ctx *ctx, char *name, struct hlsl_ir_function uint32_t hlsl_map_swizzle(uint32_t swizzle, unsigned int writemask) { + unsigned int src_component = 0; uint32_t ret = 0; - unsigned int i; /* Leave replicate swizzles alone; some instructions need them. */ if (swizzle == HLSL_SWIZZLE(X, X, X, X) @@ -4017,13 +4017,10 @@ uint32_t hlsl_map_swizzle(uint32_t swizzle, unsigned int writemask) || swizzle == HLSL_SWIZZLE(W, W, W, W)) return swizzle; - for (i = 0; i < 4; ++i) + for (unsigned int dst_component = 0; dst_component < 4; ++dst_component) { - if (writemask & (1 << i)) - { - ret |= (swizzle & 3) << (i * 2); - swizzle >>= 2; - } + if (writemask & (1 << dst_component)) + hlsl_swizzle_set_component(&ret, dst_component, hlsl_swizzle_get_component(swizzle, src_component++)); } return ret; } @@ -4076,7 +4073,7 @@ uint32_t hlsl_combine_swizzles(uint32_t first, uint32_t second, unsigned int dim for (i = 0; i < dim; ++i) { unsigned int s = hlsl_swizzle_get_component(second, i); - ret |= hlsl_swizzle_get_component(first, s) << HLSL_SWIZZLE_SHIFT(i); + hlsl_swizzle_set_component(&ret, i, hlsl_swizzle_get_component(first, s)); } return ret; } diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 122f1014..a0167971 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -77,6 +77,12 @@ static inline uint32_t vsir_swizzle_from_hlsl(uint32_t swizzle) hlsl_swizzle_get_component(swizzle, 3)); } +static inline void hlsl_swizzle_set_component(uint32_t *swizzle, unsigned int idx, unsigned int component) +{ + *swizzle &= ~(HLSL_SWIZZLE_MASK << HLSL_SWIZZLE_SHIFT(idx)); + *swizzle |= component << HLSL_SWIZZLE_SHIFT(idx); +} + enum hlsl_type_class { HLSL_CLASS_SCALAR, diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index acbfdafd..ce9f7fd6 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -909,8 +909,7 @@ static struct hlsl_ir_node *get_swizzle(struct hlsl_ctx *ctx, struct hlsl_ir_nod if (s >= value->data_type->dimx) return NULL; - swiz |= s << component * 2; - component++; + hlsl_swizzle_set_component(&swiz, component++, s); } if (valid) return hlsl_new_swizzle(ctx, swiz, component, value, loc); @@ -2087,8 +2086,8 @@ static bool invert_swizzle(uint32_t *swizzle, unsigned int *writemask, unsigned { if (*writemask & (1 << i)) { - unsigned int s = (*swizzle >> (i * 2)) & 3; - new_swizzle |= s << (bit++ * 2); + unsigned int s = hlsl_swizzle_get_component(*swizzle, i); + hlsl_swizzle_set_component(&new_swizzle, bit++, s); if (new_writemask & (1 << s)) return false; new_writemask |= 1 << s; @@ -2102,9 +2101,9 @@ static bool invert_swizzle(uint32_t *swizzle, unsigned int *writemask, unsigned { for (j = 0; j < width; ++j) { - unsigned int s = (new_swizzle >> (j * 2)) & 3; + unsigned int s = hlsl_swizzle_get_component(new_swizzle, j); if (s == i) - inverted |= j << (bit++ * 2); + hlsl_swizzle_set_component(&inverted, bit++, j); } } @@ -2148,7 +2147,7 @@ static bool invert_swizzle_matrix(const struct hlsl_matrix_swizzle *swizzle, unsigned int y = new_swizzle.components[j].y; unsigned int idx = x + y * 4; if (idx == i) - inverted |= j << (bit++ * 2); + hlsl_swizzle_set_component(&inverted, bit++, j); } } diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index f20a98ac..fbf70d00 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1631,7 +1631,7 @@ static bool copy_propagation_replace_with_single_instr(struct hlsl_ctx *ctx, var->name, start, start + count, debug_hlsl_swizzle(swizzle, instr_component_count)); return false; } - ret_swizzle |= value->component << HLSL_SWIZZLE_SHIFT(i); + hlsl_swizzle_set_component(&ret_swizzle, i, value->component); } TRACE("Load from %s[%u-%u]%s propagated as instruction %p%s.\n",