From: Zebediah Figura zfigura@codeweavers.com
--- Makefile.am | 1 + tests/hlsl/cf-cond-types.shader_test | 114 +++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 tests/hlsl/cf-cond-types.shader_test
diff --git a/Makefile.am b/Makefile.am index 648dfb255..7a6381ca4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -72,6 +72,7 @@ vkd3d_shader_tests = \ tests/hlsl/cast-to-uint.shader_test \ tests/hlsl/cbuffer.shader_test \ tests/hlsl/ceil.shader_test \ + tests/hlsl/cf-cond-types.shader_test \ tests/hlsl/clamp.shader_test \ tests/hlsl/clip.shader_test \ tests/hlsl/combined-samplers.shader_test \ diff --git a/tests/hlsl/cf-cond-types.shader_test b/tests/hlsl/cf-cond-types.shader_test new file mode 100644 index 000000000..a1bb99fee --- /dev/null +++ b/tests/hlsl/cf-cond-types.shader_test @@ -0,0 +1,114 @@ +% Condition to if/for/while must be numeric. They must also be 1-component +% (although not per se scalar — vectors and matrices are allowed, but not +% arrays). +% +% In theory an implicit conversion to bool is being performed, except that, +% unlike other places where implicit conversions are performed (assignments, +% return values) vectors are not truncated, but instead result in an error. + +[pixel shader fail] +static const float2 f; +float4 main() : sv_target +{ + if (f); + return 0; +} + +[pixel shader fail] +static const float f[1]; +float4 main() : sv_target +{ + if (f); + return 0; +} + +[pixel shader fail] +static const Texture2D f; +float4 main() : sv_target +{ + if (f); + return 0; +} + +[pixel shader fail] +static const float2 f; +float4 main() : sv_target +{ + while (f); + return 0; +} + +[pixel shader fail] +static const float f[1]; +float4 main() : sv_target +{ + while (f); + return 0; +} + +[pixel shader fail] +static const Texture2D f; +float4 main() : sv_target +{ + while (f); + return 0; +} + +[pixel shader fail] +static const float2 f; +float4 main() : sv_target +{ + do; while(f); + return 0; +} + +[pixel shader fail] +static const float f[1]; +float4 main() : sv_target +{ + do; while(f); + return 0; +} + +[pixel shader fail] +static const Texture2D f; +float4 main() : sv_target +{ + do; while(f); + return 0; +} + +[pixel shader fail] +static const float2 f; +float4 main() : sv_target +{ + for (; f;); + return 0; +} + +[pixel shader fail] +static const float f[1]; +float4 main() : sv_target +{ + for (; f;); + return 0; +} + +[pixel shader fail] +static const Texture2D f; +float4 main() : sv_target +{ + for (; f;); + return 0; +} + +[pixel shader todo] +static const float1x1 f; +float4 main() : sv_target +{ + if (f); + for (; f;); + while (f); + do; while (f); + return 0; +}
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/hlsl.y | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index c308916e0..caa88fe47 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -292,6 +292,21 @@ static bool implicit_compatible_data_types(struct hlsl_ctx *ctx, struct hlsl_typ return hlsl_types_are_componentwise_equal(ctx, src, dst); }
+static void check_condition_type(struct hlsl_ctx *ctx, const struct hlsl_ir_node *cond) +{ + const struct hlsl_type *type = cond->data_type; + + if (type->dimx > 1 || type->dimy > 1) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, type))) + hlsl_error(ctx, &cond->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Condition type '%s' is not a scalar numeric type.", string->buffer); + hlsl_release_string_buffer(ctx, string); + } +} + static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) { @@ -431,6 +446,9 @@ static bool append_conditional_break(struct hlsl_ctx *ctx, struct hlsl_block *co return true;
condition = node_from_block(cond_block); + + check_condition_type(ctx, condition); + if (!(not = hlsl_new_unary_expr(ctx, HLSL_OP1_LOGIC_NOT, condition, &condition->loc))) return false; hlsl_block_add_instr(cond_block, not); @@ -6697,15 +6715,9 @@ selection_statement: } destroy_block($6.then_block); destroy_block($6.else_block); - if (condition->data_type->dimx > 1 || condition->data_type->dimy > 1) - { - struct vkd3d_string_buffer *string;
- if ((string = hlsl_type_to_string(ctx, condition->data_type))) - hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "if condition type %s is not scalar.", string->buffer); - hlsl_release_string_buffer(ctx, string); - } + check_condition_type(ctx, condition); + $$ = $4; hlsl_block_add_instr($$, instr); }
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/hlsl.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index caa88fe47..110db99da 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -296,7 +296,7 @@ static void check_condition_type(struct hlsl_ctx *ctx, const struct hlsl_ir_node { const struct hlsl_type *type = cond->data_type;
- if (type->dimx > 1 || type->dimy > 1) + if (type->class > HLSL_CLASS_LAST_NUMERIC || type->dimx > 1 || type->dimy > 1) { struct vkd3d_string_buffer *string;
Changes look broadly fine for me, but the CI is segfaulting.