-- v2: tests: Add tests for valid conditional types. vkd3d-shader/hlsl: Validate that condition expressions are numeric. vkd3d-shader/hlsl: Validate the condition data type for loops as well. vkd3d-shader/hlsl: Copy some missing fields in hlsl_type_clone().
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/hlsl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 6a5a6d0e3..d43ea7943 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -953,6 +953,8 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, type->modifiers |= default_majority; type->sampler_dim = old->sampler_dim; type->is_minimum_precision = old->is_minimum_precision; + type->sample_count = old->sample_count; + switch (old->class) { case HLSL_CLASS_ARRAY: @@ -1002,11 +1004,11 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, }
case HLSL_CLASS_OBJECT: - { if (type->base_type == HLSL_TYPE_TECHNIQUE) type->e.version = old->e.version; + if (old->base_type == HLSL_TYPE_TEXTURE || old->base_type == HLSL_TYPE_UAV) + type->e.resource_format = old->e.resource_format; break; - }
default: break;
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;
From: Zebediah Figura zfigura@codeweavers.com
--- Makefile.am | 1 + tests/hlsl/cf-cond-types.shader_test | 131 +++++++++++++++++++++++++++ 2 files changed, 132 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..504f01477 --- /dev/null +++ b/tests/hlsl/cf-cond-types.shader_test @@ -0,0 +1,131 @@ +% 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; +} + +[pixel shader] +uniform float1 f; +float4 main() : sv_target +{ + if (f) + return 1; + return 0; +} + +[test] +uniform 0 float4 -2.0 0.0 0.0 0.0 +draw quad +probe all rgba (1.0, 1.0, 1.0, 1.0) +uniform 0 float4 -0.0 0.0 0.0 0.0 +draw quad +todo probe all rgba (0.0, 0.0, 0.0, 0.0)
Yet another failure to locally test somehow. I guess 578 was written specifically for this.