From: Francisco Casas fcasas@codeweavers.com
--- libs/vkd3d-shader/hlsl.c | 29 ++++++++++++++++++++++++++++- libs/vkd3d-shader/hlsl.h | 2 +- libs/vkd3d-shader/hlsl.y | 4 ++-- tests/object-references.shader_test | 2 +- 4 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 7fb7e6b0..07829c29 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -488,8 +488,28 @@ struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *ba return type; }
+static bool type_has_object_components(struct hlsl_type *type) +{ + if (type->type == HLSL_CLASS_OBJECT) + return true; + if (type->type == HLSL_CLASS_ARRAY) + return type_has_object_components(type->e.array.type); + + if (type->type == HLSL_CLASS_STRUCT) + { + unsigned int i; + + for (i = 0; i < type->e.record.field_count; ++i) + { + if (type_has_object_components(type->e.record.fields[i].type)) + return true; + } + } + return false; +} + struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, - struct hlsl_struct_field *fields, size_t field_count) + struct hlsl_struct_field *fields, size_t field_count, const struct vkd3d_shader_location *loc) { struct hlsl_type *type;
@@ -501,6 +521,13 @@ struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, type->dimy = 1; type->e.record.fields = fields; type->e.record.field_count = field_count; + + if (ctx->profile->major_version < 5 && type_has_object_components(type)) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Target profile doesn't support objects as struct members.\n"); + } + hlsl_type_calculate_reg_size(ctx, type);
list_add_tail(&ctx->types, &type->entry); diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 724d157e..a832c6a6 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -782,7 +782,7 @@ struct hlsl_ir_loop *hlsl_new_loop(struct hlsl_ctx *ctx, struct vkd3d_shader_loc struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc); struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, - struct hlsl_struct_field *fields, size_t field_count); + struct hlsl_struct_field *fields, size_t field_count, const struct vkd3d_shader_location *loc); struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned int components, struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc); struct hlsl_ir_var *hlsl_new_synthetic_var(struct hlsl_ctx *ctx, const char *template, diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 7ada218c..a84e37ba 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3307,7 +3307,7 @@ named_struct_spec: { bool ret;
- $$ = hlsl_new_struct_type(ctx, $2, $4.fields, $4.count); + $$ = hlsl_new_struct_type(ctx, $2, $4.fields, $4.count, &@$);
if (hlsl_get_var(ctx->cur_scope, $2)) { @@ -3326,7 +3326,7 @@ named_struct_spec: unnamed_struct_spec: KW_STRUCT '{' fields_list '}' { - $$ = hlsl_new_struct_type(ctx, NULL, $3.fields, $3.count); + $$ = hlsl_new_struct_type(ctx, NULL, $3.fields, $3.count, &@$); }
any_identifier: diff --git a/tests/object-references.shader_test b/tests/object-references.shader_test index 6cff351a..56d58804 100644 --- a/tests/object-references.shader_test +++ b/tests/object-references.shader_test @@ -1,5 +1,5 @@ [require] -shader model >= 4.0 +shader model >= 5.0
[texture 0] size (2, 2)