Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 4 ++-- libs/vkd3d-shader/hlsl.h | 28 ++++++++++++++++++++++++++++ libs/vkd3d-shader/hlsl.y | 28 ++++++++++++---------------- 3 files changed, 42 insertions(+), 18 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 9bce6beb..8a56025d 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -560,7 +560,7 @@ struct hlsl_ir_constant *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned i
if (!(c = hlsl_alloc(ctx, sizeof(*c)))) return NULL; - init_node(&c->node, HLSL_IR_CONSTANT, ctx->builtin_types.scalar[HLSL_TYPE_UINT], loc); + init_node(&c->node, HLSL_IR_CONSTANT, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc); c->value[0].u = n; return c; } @@ -650,7 +650,7 @@ struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned if (!(swizzle = hlsl_alloc(ctx, sizeof(*swizzle)))) return NULL; init_node(&swizzle->node, HLSL_IR_SWIZZLE, - ctx->builtin_types.vector[val->data_type->base_type][components - 1], *loc); + hlsl_get_vector_type(ctx, val->data_type->base_type, components), *loc); hlsl_src_from_node(&swizzle->val, val); swizzle->swizzle = s; return swizzle; diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index e401971e..31b7ddbb 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -629,6 +629,34 @@ static inline void hlsl_release_string_buffer(struct hlsl_ctx *ctx, struct vkd3d vkd3d_string_buffer_release(&ctx->string_buffers, buffer); }
+static inline struct hlsl_type *hlsl_get_scalar_type(const struct hlsl_ctx *ctx, enum hlsl_base_type base_type) +{ + return ctx->builtin_types.scalar[base_type]; +} + +static inline struct hlsl_type *hlsl_get_vector_type(const struct hlsl_ctx *ctx, enum hlsl_base_type base_type, + unsigned int dimx) +{ + return ctx->builtin_types.vector[base_type][dimx - 1]; +} + +static inline struct hlsl_type *hlsl_get_matrix_type(const struct hlsl_ctx *ctx, enum hlsl_base_type base_type, + unsigned int dimx, unsigned int dimy) +{ + return ctx->builtin_types.matrix[base_type][dimx - 1][dimy - 1]; +} + +static inline struct hlsl_type *hlsl_get_numeric_type(const struct hlsl_ctx *ctx, enum hlsl_type_class type, + enum hlsl_base_type base_type, unsigned int dimx, unsigned int dimy) +{ + if (type == HLSL_CLASS_SCALAR) + return hlsl_get_scalar_type(ctx, base_type); + else if (type == HLSL_CLASS_VECTOR) + return hlsl_get_vector_type(ctx, base_type, dimx); + else + return hlsl_get_matrix_type(ctx, base_type, dimx, dimy); +} + const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op); const char *debug_hlsl_type(struct hlsl_ctx *ctx, const struct hlsl_type *type); const char *debug_hlsl_writemask(unsigned int writemask); diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index ae19cd1a..61789def 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1021,11 +1021,7 @@ static struct hlsl_type *expr_common_type(struct hlsl_ctx *ctx, struct hlsl_type } }
- if (type == HLSL_CLASS_SCALAR) - return ctx->builtin_types.scalar[base]; - if (type == HLSL_CLASS_VECTOR) - return ctx->builtin_types.vector[base][dimx - 1]; - return ctx->builtin_types.matrix[base][dimx - 1][dimy - 1]; + return hlsl_get_numeric_type(ctx, type, base, dimx, dimy); }
static struct hlsl_ir_expr *add_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, @@ -1761,7 +1757,7 @@ static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type }
if (!(arg = add_implicit_conversion(ctx, params->instrs, arg, - ctx->builtin_types.vector[type->base_type][width - 1], &arg->loc))) + hlsl_get_vector_type(ctx, type->base_type, width), &arg->loc))) continue;
if (!(store = hlsl_new_store(ctx, var, NULL, arg, @@ -1816,9 +1812,9 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl if (params->args_count >= 2) FIXME("Ignoring index and/or offset parameter(s).\n");
- /* -1 for zero-indexing; +1 for the mipmap level */ + /* +1 for the mipmap level */ if (!(coords = add_implicit_conversion(ctx, instrs, params->args[0], - ctx->builtin_types.vector[HLSL_TYPE_INT][sampler_dim - 1 + 1], loc))) + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim + 1), loc))) return false;
if (!(load = hlsl_new_resource_load(ctx, object_type->e.resource_format, HLSL_RESOURCE_LOAD, @@ -2500,7 +2496,7 @@ type: YYABORT; }
- $$ = ctx->builtin_types.vector[$3->base_type][$5 - 1]; + $$ = hlsl_get_vector_type(ctx, $3->base_type, $5); } | KW_MATRIX '<' type ',' C_INTEGER ',' C_INTEGER '>' { @@ -2528,7 +2524,7 @@ type: YYABORT; }
- $$ = ctx->builtin_types.matrix[$3->base_type][$7 - 1][$5 - 1]; + $$ = hlsl_get_matrix_type(ctx, $3->base_type, $7, $5); } | KW_VOID { @@ -2560,7 +2556,7 @@ type: } | texture_type { - $$ = hlsl_new_texture_type(ctx, $1, ctx->builtin_types.vector[HLSL_TYPE_FLOAT][4 - 1]); + $$ = hlsl_new_texture_type(ctx, $1, hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4)); } | texture_type '<' type '>' { @@ -2971,7 +2967,7 @@ primary_expr:
if (!(c = hlsl_alloc(ctx, sizeof(*c)))) YYABORT; - init_node(&c->node, HLSL_IR_CONSTANT, ctx->builtin_types.scalar[HLSL_TYPE_FLOAT], @1); + init_node(&c->node, HLSL_IR_CONSTANT, hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), @1); c->value[0].f = $1; if (!($$ = make_list(ctx, &c->node))) YYABORT; @@ -2982,7 +2978,7 @@ primary_expr:
if (!(c = hlsl_alloc(ctx, sizeof(*c)))) YYABORT; - init_node(&c->node, HLSL_IR_CONSTANT, ctx->builtin_types.scalar[HLSL_TYPE_INT], @1); + init_node(&c->node, HLSL_IR_CONSTANT, hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), @1); c->value[0].i = $1; if (!($$ = make_list(ctx, &c->node))) YYABORT; @@ -2993,7 +2989,7 @@ primary_expr:
if (!(c = hlsl_alloc(ctx, sizeof(*c)))) YYABORT; - init_node(&c->node, HLSL_IR_CONSTANT, ctx->builtin_types.scalar[HLSL_TYPE_BOOL], @1); + init_node(&c->node, HLSL_IR_CONSTANT, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), @1); c->value[0].b = $1; if (!($$ = make_list(ctx, &c->node))) YYABORT; @@ -3030,7 +3026,7 @@ primary_expr: struct hlsl_ir_var *var;
if (!(var = hlsl_new_synthetic_var(ctx, "<state-block-expr>", - ctx->builtin_types.scalar[HLSL_TYPE_INT], @1))) + hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), @1))) YYABORT; if (!(load = hlsl_new_var_load(ctx, var, @1))) YYABORT; @@ -3116,7 +3112,7 @@ postfix_expr: YYABORT; }
- if (!(cast = hlsl_new_cast(ctx, index, ctx->builtin_types.scalar[HLSL_TYPE_UINT], &index->loc))) + if (!(cast = hlsl_new_cast(ctx, index, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &index->loc))) { destroy_instr_list($1); YYABORT;
Function expr_common_shape can be used for boolean operators, for which a common shape must be determined even if the base type of the result is always bool.
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 82 +++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 38 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 61789def..5f320323 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -912,13 +912,9 @@ static enum hlsl_base_type expr_common_base_type(enum hlsl_base_type t1, enum hl return HLSL_TYPE_INT; }
-static struct hlsl_type *expr_common_type(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct hlsl_type *t2, - struct vkd3d_shader_location *loc) +static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct hlsl_type *t2, + struct vkd3d_shader_location *loc, enum hlsl_type_class *type, unsigned int *dimx, unsigned int *dimy) { - enum hlsl_type_class type; - enum hlsl_base_type base; - unsigned int dimx, dimy; - if (t1->type > HLSL_CLASS_LAST_NUMERIC) { struct vkd3d_string_buffer *string; @@ -927,7 +923,7 @@ static struct hlsl_type *expr_common_type(struct hlsl_ctx *ctx, struct hlsl_type hlsl_error(ctx, *loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Expression of type "%s" cannot be used in a numeric expression.", string->buffer); hlsl_release_string_buffer(ctx, string); - return NULL; + return false; }
if (t2->type > HLSL_CLASS_LAST_NUMERIC) @@ -938,12 +934,9 @@ static struct hlsl_type *expr_common_type(struct hlsl_ctx *ctx, struct hlsl_type hlsl_error(ctx, *loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Expression of type "%s" cannot be used in a numeric expression.", string->buffer); hlsl_release_string_buffer(ctx, string); - return NULL; + return false; }
- if (hlsl_types_are_equal(t1, t2)) - return t1; - if (!expr_compatible_data_types(t1, t2)) { struct vkd3d_string_buffer *t1_string = hlsl_type_to_string(ctx, t1); @@ -955,28 +948,26 @@ static struct hlsl_type *expr_common_type(struct hlsl_ctx *ctx, struct hlsl_type t1_string->buffer, t2_string->buffer); hlsl_release_string_buffer(ctx, t1_string); hlsl_release_string_buffer(ctx, t2_string); - return NULL; + return false; }
- base = expr_common_base_type(t1->base_type, t2->base_type); - if (t1->dimx == 1 && t1->dimy == 1) { - type = t2->type; - dimx = t2->dimx; - dimy = t2->dimy; + *type = t2->type; + *dimx = t2->dimx; + *dimy = t2->dimy; } else if (t2->dimx == 1 && t2->dimy == 1) { - type = t1->type; - dimx = t1->dimx; - dimy = t1->dimy; + *type = t1->type; + *dimx = t1->dimx; + *dimy = t1->dimy; } else if (t1->type == HLSL_CLASS_MATRIX && t2->type == HLSL_CLASS_MATRIX) { - type = HLSL_CLASS_MATRIX; - dimx = min(t1->dimx, t2->dimx); - dimy = min(t1->dimy, t2->dimy); + *type = HLSL_CLASS_MATRIX; + *dimx = min(t1->dimx, t2->dimx); + *dimy = min(t1->dimy, t2->dimy); } else { @@ -987,40 +978,55 @@ static struct hlsl_type *expr_common_type(struct hlsl_ctx *ctx, struct hlsl_type max_dim_2 = max(t2->dimx, t2->dimy); if (t1->dimx * t1->dimy == t2->dimx * t2->dimy) { - type = HLSL_CLASS_VECTOR; - dimx = max(t1->dimx, t2->dimx); - dimy = 1; + *type = HLSL_CLASS_VECTOR; + *dimx = max(t1->dimx, t2->dimx); + *dimy = 1; } else if (max_dim_1 <= max_dim_2) { - type = t1->type; - if (type == HLSL_CLASS_VECTOR) + *type = t1->type; + if (*type == HLSL_CLASS_VECTOR) { - dimx = max_dim_1; - dimy = 1; + *dimx = max_dim_1; + *dimy = 1; } else { - dimx = t1->dimx; - dimy = t1->dimy; + *dimx = t1->dimx; + *dimy = t1->dimy; } } else { - type = t2->type; - if (type == HLSL_CLASS_VECTOR) + *type = t2->type; + if (*type == HLSL_CLASS_VECTOR) { - dimx = max_dim_2; - dimy = 1; + *dimx = max_dim_2; + *dimy = 1; } else { - dimx = t2->dimx; - dimy = t2->dimy; + *dimx = t2->dimx; + *dimy = t2->dimy; } } }
+ return true; +} + +static struct hlsl_type *expr_common_type(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct hlsl_type *t2, + struct vkd3d_shader_location *loc) +{ + enum hlsl_type_class type; + enum hlsl_base_type base; + unsigned int dimx, dimy; + + if (!expr_common_shape(ctx, t1, t2, loc, &type, &dimx, &dimy)) + return NULL; + + base = expr_common_base_type(t1->base_type, t2->base_type); + return hlsl_get_numeric_type(ctx, type, base, dimx, dimy); }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
When t1 is a vector type, it's already supposed to have dimx == max_dim_1 and dimy == 1, and the same for t2.
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 5f320323..d2cc1878 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -985,30 +985,14 @@ static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct else if (max_dim_1 <= max_dim_2) { *type = t1->type; - if (*type == HLSL_CLASS_VECTOR) - { - *dimx = max_dim_1; - *dimy = 1; - } - else - { - *dimx = t1->dimx; - *dimy = t1->dimy; - } + *dimx = t1->dimx; + *dimy = t1->dimy; } else { *type = t2->type; - if (*type == HLSL_CLASS_VECTOR) - { - *dimx = max_dim_2; - *dimy = 1; - } - else - { - *dimx = t2->dimx; - *dimy = t2->dimy; - } + *dimx = t2->dimx; + *dimy = t2->dimy; } }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
The assumption about the size of matrices is not correct: it is legitimate to compose a matrix 2x2 with a vector of length 4, in which case it appears that the result has the shape of the first (leftmost) operand. Even for matrices 1xN or Nx1, the result is not always a vector: in general it has the shape of the first operand again.
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index d2cc1878..249d1bfd 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -971,18 +971,7 @@ static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct } else { - /* Two vectors or a vector and a matrix (matrix must be 1xn or nx1) */ - unsigned int max_dim_1, max_dim_2; - - max_dim_1 = max(t1->dimx, t1->dimy); - max_dim_2 = max(t2->dimx, t2->dimy); - if (t1->dimx * t1->dimy == t2->dimx * t2->dimy) - { - *type = HLSL_CLASS_VECTOR; - *dimx = max(t1->dimx, t2->dimx); - *dimy = 1; - } - else if (max_dim_1 <= max_dim_2) + if (t1->dimx * t1->dimy <= t2->dimx * t2->dimy) { *type = t1->type; *dimx = t1->dimx;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- ...lsl-return-implicit-conversion.shader_test | 235 ++++++++++++++++++ 1 file changed, 235 insertions(+)
diff --git a/tests/hlsl-return-implicit-conversion.shader_test b/tests/hlsl-return-implicit-conversion.shader_test index 527387b3..654b51cf 100644 --- a/tests/hlsl-return-implicit-conversion.shader_test +++ b/tests/hlsl-return-implicit-conversion.shader_test @@ -7,3 +7,238 @@ float4 main() : sv_target [test] draw quad probe all rgba (0.4, 0.3, 0.2, 0.1) + +[pixel shader] +float4 main() : sv_target +{ + return float1x4(0.4, 0.3, 0.2, 0.1); +} + +[test] +draw quad +probe all rgba (0.4, 0.3, 0.2, 0.1) + +[pixel shader] +float4 main() : sv_target +{ + return float4x1(0.4, 0.3, 0.2, 0.1); +} + +[test] +draw quad +probe all rgba (0.4, 0.3, 0.2, 0.1) + +[pixel shader] +float4x1 main() : sv_target +{ + return float4(0.4, 0.3, 0.2, 0.1); +} + +[test] +draw quad +probe all rgba (0.4, 0.3, 0.2, 0.1) + +[pixel shader] +float3 func() +{ + return float3x1(0.4, 0.3, 0.2); +} + +float4 main() : sv_target +{ + return float4(func(), 0.0); +} + +[test] +draw quad +probe all rgba (0.4, 0.3, 0.2, 0.0) + +[pixel shader] +float3 func() +{ + return float1x3(0.4, 0.3, 0.2); +} + +float4 main() : sv_target +{ + return float4(func(), 0.0); +} + +[test] +draw quad +probe all rgba (0.4, 0.3, 0.2, 0.0) + +[pixel shader] +float1x3 func() +{ + return float3(0.4, 0.3, 0.2); +} + +float4 main() : sv_target +{ + return float4(func(), 0.0); +} + +[test] +draw quad +probe all rgba (0.4, 0.3, 0.2, 0.0) + +[pixel shader] +float3x1 func() +{ + return float3(0.4, 0.3, 0.2); +} + +float4 main() : sv_target +{ + return float4(func(), 0.0); +} + +[test] +draw quad +probe all rgba (0.4, 0.3, 0.2, 0.0) + +[pixel shader fail] +float3x1 func() +{ + return float1x3(0.4, 0.3, 0.2); +} + +float4 main() : sv_target +{ + return float4(func(), 0.0); +} + +[pixel shader fail] +float1x3 func() +{ + return float3x1(0.4, 0.3, 0.2); +} + +float4 main() : sv_target +{ + return float4(func(), 0.0); +} + +[pixel shader] +float3 func() +{ + return float4(0.4, 0.3, 0.2, 0.1); +} + +float4 main() : sv_target +{ + return float4(func(), 0.0); +} + +[test] +draw quad +probe all rgba (0.4, 0.3, 0.2, 0.0) + +[pixel shader] +float3 func() +{ + return float4x1(0.4, 0.3, 0.2, 0.1); +} + +float4 main() : sv_target +{ + return float4(func(), 0.0); +} + +[test] +draw quad +probe all rgba (0.4, 0.3, 0.2, 0.0) + +[pixel shader] +float3 func() +{ + return float1x4(0.4, 0.3, 0.2, 0.1); +} + +float4 main() : sv_target +{ + return float4(func(), 0.0); +} + +[test] +draw quad +probe all rgba (0.4, 0.3, 0.2, 0.0) + +[pixel shader fail] +float3x1 func() +{ + return float4(0.4, 0.3, 0.2, 0.1); +} + +float4 main() : sv_target +{ + return float4(func(), 0.0); +} + +[pixel shader] +float3x1 func() +{ + return float4x1(0.4, 0.3, 0.2, 0.1); +} + +float4 main() : sv_target +{ + return float4(func(), 0.0); +} + +[test] +draw quad +probe all rgba (0.4, 0.3, 0.2, 0.0) + +[pixel shader fail] +float3x1 func() +{ + return float1x4(0.4, 0.3, 0.2, 0.1); +} + +float4 main() : sv_target +{ + return float4(func(), 0.0); +} + +[pixel shader] +float1x3 func() +{ + return float4(0.4, 0.3, 0.2, 0.1); +} + +float4 main() : sv_target +{ + return float4(func(), 0.0); +} + +[test] +draw quad +probe all rgba (0.4, 0.3, 0.2, 0.0) + +[pixel shader fail] +float1x3 func() +{ + return float4x1(0.4, 0.3, 0.2, 0.1); +} + +float4 main() : sv_target +{ + return float4(func(), 0.0); +} + +[pixel shader] +float1x3 func() +{ + return float1x4(0.4, 0.3, 0.2, 0.1); +} + +float4 main() : sv_target +{ + return float4(func(), 0.0); +} + +[test] +draw quad +probe all rgba (0.4, 0.3, 0.2, 0.0)
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
HLSL seems to treat matrices 1xN or Nx1 as vectors when looking for implicit conversions.
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 249d1bfd..a2e27b5d 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -240,14 +240,22 @@ static bool implicit_compatible_data_types(struct hlsl_type *t1, struct hlsl_typ
if (t1->type == HLSL_CLASS_MATRIX || t2->type == HLSL_CLASS_MATRIX) { - if (t1->type == HLSL_CLASS_MATRIX && t2->type == HLSL_CLASS_MATRIX - && t1->dimx >= t2->dimx && t1->dimy >= t2->dimy) - return true; + if (t1->type == HLSL_CLASS_MATRIX && t2->type == HLSL_CLASS_MATRIX) + return t1->dimx >= t2->dimx && t1->dimy >= t2->dimy; + + /* Matrix-vector conversion is apparently allowed if they have + * the same components count, or if the matrix is 1xN or Nx1 + * and we are reducing the component count */ + if (t1->type == HLSL_CLASS_VECTOR || t2->type == HLSL_CLASS_VECTOR) + { + if (hlsl_type_component_count(t1) == hlsl_type_component_count(t2)) + return true; + + if ((t1->type == HLSL_CLASS_VECTOR || t1->dimx == 1 || t1->dimy == 1) && + (t2->type == HLSL_CLASS_VECTOR || t2->dimx == 1 || t2->dimy == 1)) + return hlsl_type_component_count(t1) >= hlsl_type_component_count(t2); + }
- /* Matrix-vector conversion is apparently allowed if they have the same components count */ - if ((t1->type == HLSL_CLASS_VECTOR || t2->type == HLSL_CLASS_VECTOR) - && hlsl_type_component_count(t1) == hlsl_type_component_count(t2)) - return true; return false; }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com