From: Francisco Casas fcasas@codeweavers.com
--- libs/vkd3d-shader/hlsl.y | 93 +++++++++++----------- tests/cast-componentwise-equal.shader_test | 16 ++-- 2 files changed, 54 insertions(+), 55 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index f5f114c8..e14760d8 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -153,6 +153,27 @@ static bool convertible_data_type(struct hlsl_type *type) return type->type != HLSL_CLASS_OBJECT; }
+static bool hlsl_types_are_componentwise_equal(struct hlsl_ctx *ctx, struct hlsl_type *src, + struct hlsl_type *dst) +{ + unsigned int k, count = hlsl_type_component_count(src); + + if (count != hlsl_type_component_count(dst)) + return false; + + for (k = 0; k < count; ++k) + { + struct hlsl_type *src_comp_type, *dst_comp_type; + + src_comp_type = hlsl_type_get_component_type(ctx, src, k); + dst_comp_type = hlsl_type_get_component_type(ctx, dst, k); + + if (!hlsl_types_are_equal(src_comp_type, dst_comp_type)) + return false; + } + return true; +} + static bool compatible_data_types(struct hlsl_type *src, struct hlsl_type *dst) { if (!convertible_data_type(src) || !convertible_data_type(dst)) @@ -207,69 +228,47 @@ static bool compatible_data_types(struct hlsl_type *src, struct hlsl_type *dst) return false; }
-static bool implicit_compatible_data_types(struct hlsl_type *src, struct hlsl_type *dst) +static bool implicit_compatible_data_types(struct hlsl_ctx *ctx, struct hlsl_type *src, struct hlsl_type *dst) { - if (!convertible_data_type(src) || !convertible_data_type(dst)) + if ((src->type <= HLSL_CLASS_LAST_NUMERIC) != (dst->type <= HLSL_CLASS_LAST_NUMERIC)) return false;
if (src->type <= HLSL_CLASS_LAST_NUMERIC) { /* Scalar vars can be converted to any other numeric data type */ - if (src->dimx == 1 && src->dimy == 1 && dst->type <= HLSL_CLASS_LAST_NUMERIC) + if (src->dimx == 1 && src->dimy == 1) return true; /* The other way around is true too */ - if (dst->dimx == 1 && dst->dimy == 1 && dst->type <= HLSL_CLASS_LAST_NUMERIC) + if (dst->dimx == 1 && dst->dimy == 1) return true; - }
- if (src->type == HLSL_CLASS_ARRAY && dst->type == HLSL_CLASS_ARRAY) - { - return hlsl_type_component_count(src) == hlsl_type_component_count(dst); - } - - if ((src->type == HLSL_CLASS_ARRAY && dst->type <= HLSL_CLASS_LAST_NUMERIC) - || (src->type <= HLSL_CLASS_LAST_NUMERIC && dst->type == HLSL_CLASS_ARRAY)) - { - /* e.g. float4[3] to float4 is allowed */ - if (src->type == HLSL_CLASS_ARRAY && hlsl_types_are_equal(src->e.array.type, dst)) - return true; - if (hlsl_type_component_count(src) == hlsl_type_component_count(dst)) - return true; - return false; - } + if (src->type == HLSL_CLASS_MATRIX || dst->type == HLSL_CLASS_MATRIX) + { + if (src->type == HLSL_CLASS_MATRIX && dst->type == HLSL_CLASS_MATRIX) + return src->dimx >= dst->dimx && src->dimy >= dst->dimy;
- if (src->type <= HLSL_CLASS_VECTOR && dst->type <= HLSL_CLASS_VECTOR) - { - if (src->dimx >= dst->dimx) - return true; - return false; - } + /* 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 (src->type == HLSL_CLASS_VECTOR || dst->type == HLSL_CLASS_VECTOR) + { + if (hlsl_type_component_count(src) == hlsl_type_component_count(dst)) + return true;
- if (src->type == HLSL_CLASS_MATRIX || dst->type == HLSL_CLASS_MATRIX) - { - if (src->type == HLSL_CLASS_MATRIX && dst->type == HLSL_CLASS_MATRIX) - return src->dimx >= dst->dimx && src->dimy >= dst->dimy; + if ((src->type == HLSL_CLASS_VECTOR || src->dimx == 1 || src->dimy == 1) && + (dst->type == HLSL_CLASS_VECTOR || dst->dimx == 1 || dst->dimy == 1)) + return hlsl_type_component_count(src) >= hlsl_type_component_count(dst); + }
- /* 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 (src->type == HLSL_CLASS_VECTOR || dst->type == HLSL_CLASS_VECTOR) + return false; + } + else { - if (hlsl_type_component_count(src) == hlsl_type_component_count(dst)) - return true; - - if ((src->type == HLSL_CLASS_VECTOR || src->dimx == 1 || src->dimy == 1) && - (dst->type == HLSL_CLASS_VECTOR || dst->dimx == 1 || dst->dimy == 1)) - return hlsl_type_component_count(src) >= hlsl_type_component_count(dst); + return src->dimx >= dst->dimx; } - - return false; }
- if (src->type == HLSL_CLASS_STRUCT && dst->type == HLSL_CLASS_STRUCT) - return hlsl_types_are_equal(src, dst); - - return false; + return hlsl_types_are_componentwise_equal(ctx, src, dst); }
static struct hlsl_ir_load *add_load_component(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_instr, @@ -364,7 +363,7 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct if (hlsl_types_are_equal(src_type, dst_type)) return node;
- if (!implicit_compatible_data_types(src_type, dst_type)) + if (!implicit_compatible_data_types(ctx, src_type, dst_type)) { struct vkd3d_string_buffer *src_string, *dst_string;
diff --git a/tests/cast-componentwise-equal.shader_test b/tests/cast-componentwise-equal.shader_test index ac329112..d0775f47 100644 --- a/tests/cast-componentwise-equal.shader_test +++ b/tests/cast-componentwise-equal.shader_test @@ -50,8 +50,8 @@ float4 main() : sv_target
[test] -todo draw quad -todo probe all rgba (1.0, 2.0, 3.0, 1.0) +draw quad +probe all rgba (1.0, 2.0, 3.0, 1.0)
[pixel shader fail] @@ -89,8 +89,8 @@ float4 main() : sv_target
[test] -todo draw quad -todo probe all rgba (5.0, 6.0, 7.0, 8.0) +draw quad +probe all rgba (5.0, 6.0, 7.0, 8.0)
[pixel shader] @@ -120,8 +120,8 @@ float4 main() : sv_target }
[test] -todo draw quad -todo probe all rgba (4.0, 4.0, 4.0, 4.0) +draw quad +probe all rgba (4.0, 4.0, 4.0, 4.0)
[pixel shader] @@ -199,8 +199,8 @@ float4 main() : sv_target }
[test] -todo draw quad -todo probe all rgba (71.0, 73.0, 73.0, 74.0) +draw quad +probe all rgba (71.0, 73.0, 73.0, 74.0)
[pixel shader fail]